每次方法调用时,ArrayList大小缩小1

时间:2015-12-11 04:20:46

标签: java arraylist methods call

快速提问。我目前正在制作合成分割计算器,作为其中的一部分,我需要测试P / Q(双精度)是否可以作为等式中的因子(作为整数列表给出方法)。 / p>

这是我在主类中的代码:

public static void main(String[] args)
{
    List<Integer> coeffs = new ArrayList<>();
    coeffs.add(1);
    coeffs.add(-6);
    coeffs.add(11);
    coeffs.add(-6);
    System.out.println(coeffs); // Returns [1, -6, 11, -6]
    System.out.println(doesPqWork(coeffs, 1)); // Returns 'true' as intended
    System.out.println(coeffs); // Returns [-6, 11, -6]
    System.out.println(doesPqWork(coeffs, -2)); // Returns 'false' not as intended
    System.out.println(coeffs); // Returns [11, -6]
    System.out.println(doesPqWork(coeffs, 3)); // Returns 'false' not as intended
    System.out.println(coeffs); // Returns [-6]
}

这是P / Q方法本身:

private static boolean doesPqWork(List<Integer> coefficients, double PQ)
{
    List<Double> results = new ArrayList<>();
    double lastResult = coefficients.get(0);
    coefficients.remove(0);
    for(int coeff : coefficients) // 2, 1
    {
        double multiplied = PQ * lastResult;
        lastResult = coeff + multiplied;
        results.add(lastResult);
    }
    return results.get(results.size() - 1) == 0;
}

请忽略此方法如何计算它,我只是想知道为什么在地球上&#34; coeffs&#34; ArrayList每次都在缩小。我已经用Java编写了两年的代码,而且我从未遇到过这个问题。

我认为这是因为当我打电话给&#34; coefficient.remove(0)&#34;由于某种原因,它可以链接到&#34; coeffs&#34;在&#34; main&#34;中列出方法,但是当我创建一个不可能链接回去的新变量时,它仍然很奇怪。

我知道一种方法可以通过创建一些不连贯的代码和重复变量来解决这个问题,但这看起来真的很浪费我真的想知道这种意外行为的来源,所以我可以解决它。

我可能在这里犯了一个愚蠢的错误,但如果我不是,那么有人可以向我解释一下这是怎么回事?哈哈。

4 个答案:

答案 0 :(得分:0)

Java中的对象(例如Array s)不作为副本传递。您的函数接收对传入的参数的引用,因此当您调用coefficients.remove(0)时,您将删除从main()coeffs数组)传递的数组的第一个元素。

答案 1 :(得分:0)

啊哈!这是答案OP。

当您返回results.get(results.size()-1) == 0; .size()-1缩小阵列时。这是因为当您查看代码时,您正在将数组列表coeffs直接传递给该方法并将其更改为b / c,如@par表示您正在传递引用而不是副本。

编辑:这是修改代码的最简单方法。

public static void main(String[] args) {
        List<Integer> coeffs = new ArrayList<>();
        coeffs.add(1);
        coeffs.add(-6);
        coeffs.add(11);
        coeffs.add(-6);
        List<Integer> coeffCopy = new ArrayList(coeffs);
        System.out.println(coeffs); // Returns [1, -6, 11, -6]
        System.out.println(doesPqWork(coeffCopy, 1)); // Returns 'true' as intended
        System.out.println(coeffCopy); // Returns [-6, 11, -6]
        System.out.println(doesPqWork(coeffCopy, -2)); // Returns 'false' not as intended
        System.out.println(coeffs); // Returns [11, -6]
        System.out.println(doesPqWork(coeffCopy, 3)); // Returns 'false' not as intended
        System.out.println(coeffs); // Returns [-6]
    }

    private static boolean doesPqWork(List<Integer> coefficients, double PQ) {

        List<Double> results = new ArrayList<>();
        double lastResult = coefficients.get(0);
        coefficients.remove(0);
        for (int coeff : coefficients) // 2, 1
        {
            double multiplied = PQ * lastResult;
            lastResult = coeff + multiplied;
            results.add(lastResult);
        }
        return results.get(results.size() - 1) == 0;
    }

答案 2 :(得分:-1)

这是因为你正在呼叫coefficients.remove(0)

然而,

Java是按值传递的;它将对象的引用传递给值。见Is Java "pass-by-reference" or "pass-by-value"?

因此,在您的情况下,您传递的是coeffs ArrayList,实际上是在doesPqWork()内操纵它。

仅创建新引用也不会修复它。即ArrayList<Integer> tmp = coeffs;只是创建了另一个引用,而不是“副本”。

一种可行的解决方案是将coeffs对象的“副本”发送给doesPqWork(),例如doesPqWork(new ArrayList<Integer>(coeffs), 1));

这将创建一个与coeffs具有相同值的新对象。

How do I clone a generic List in Java?也可能会有所帮助。

答案 3 :(得分:-1)

您需要复制数组:

    private static boolean doesPqWork(List<Integer> coefficients, double PQ) {


    // here you need to copy the coefficients. for example:
    List<Integer> copyOfCoeffs = new ArrayList<Integer>(coefficients);

    List<Double> results = new ArrayList<>();
    double lastResult = copyOfcoeffs.get(0);
    copyOfcoeffs.remove(0);
    for(int coeff : coefficients) // 2, 1
    {
        double multiplied = PQ * lastResult;
        lastResult = coeff + multiplied;
        results.add(lastResult);
    }
    return results.get(results.size() - 1) == 0;
}