快速提问。我目前正在制作合成分割计算器,作为其中的一部分,我需要测试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;中列出方法,但是当我创建一个不可能链接回去的新变量时,它仍然很奇怪。
我知道一种方法可以通过创建一些不连贯的代码和重复变量来解决这个问题,但这看起来真的很浪费我真的想知道这种意外行为的来源,所以我可以解决它。
我可能在这里犯了一个愚蠢的错误,但如果我不是,那么有人可以向我解释一下这是怎么回事?哈哈。
答案 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
具有相同值的新对象。
答案 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;
}