英文:
Why is one of the variables in an object being changed within a constructor?
问题
抱歉我用于代码的语言处理器无法直接处理代码块。如果你能提供文本描述,我可以翻译成中文。
英文:
I apologise for the poorly worded question - it is hard to explain consisely.
I have written 3 classes - one to represent complex numbers, one to represent polynomials with complex coefficients and the final to perform Newton-Raphson algorithm on said polynomials to find estimates of roots.
The problem is, when i create an instance of the Newton class, with this being the constructor:
public Newton(Polynomial p) {
this.f = p;
this.fp = this.f.derivative();
it has no problem with setting f to p, but then when
this.fp = this.f.derivative();
is run it changes this.f to this.f.derivative(); too.
this is the code for the derivative:
public Polynomial derivative() {
ArrayList<Complex> derivativeCoeff = coeff;
if (derivativeCoeff.size() == 1){
return new Polynomial();
}
derivativeCoeff.remove(0);
for (int i = 1; i <= derivativeCoeff.size() ;i++){
derivativeCoeff.set(i-1,derivativeCoeff.get(i-1).multiply(i));
}
Polynomial test = new Polynomial(derivativeCoeff);
return test;
}
This is the main for Newton:
ArrayList<Complex> coeff = new ArrayList<Complex>();
coeff.add(new Complex(-1.0,0.0));
coeff.add(new Complex());
coeff.add(new Complex());
coeff.add(new Complex(1.0,0.0));
Polynomial p = new Polynomial(coeff);
System.out.println("the polynomial being used = "+p);
Newton n = new Newton(p);
System.out.println("f = "+n.getF());
System.out.println("fp = "+n.getFp());
and this is the output I get:
the polynomial being used = (-1.0+0.0i)+(0.0+0.0i)X+(0.0+0.0i)X^2+(1.0+0.0i)X^3
f = (0.0+0.0i)+(0.0+0.0i)X+(3.0+0.0i)X^2
fp = (0.0+0.0i)+(0.0+0.0i)X+(3.0+0.0i)X^2
when f should be equal to p.
Please ask if any more information or code is required. I am not experienced with asking questions on SO and would appreciate any help I can get.
答案1
得分: 4
ArrayList<Complex> derivativeCoeff = coeff;
不会复制列表:更新derivativeCoeff
也会更新coeff
。
进行复制:
ArrayList<Complex> derivativeCoeff = new ArrayList<>(coeff);
或者,在进行复制之前可以先移除第一个元素(显然要先检查是否为空):
ArrayList<Complex> derivativeCoeff = new ArrayList<>(coeff.subList(1, coeff.size()));
或者可以直接使用流复制并更新元素。
ArrayList<Complex> derivativeCoeff =
IntStream.rangeClosed(1, coeff.size() - 1)
.mapToObj(i -> coeff.get(i).multiply(i))
.collect(Collectors.toCollection(ArrayList::new));
甚至可以:
return
IntStream.rangeClosed(1, coeff.size() - 1)
.mapToObj(i -> coeff.get(i).multiply(i))
.collect(
Collectors.collectingAndThen(
Collectors.toCollection(ArrayList::new)),
Polynomial::new));
英文:
ArrayList<Complex> derivativeCoeff = coeff;
Doesn't copy the list: updating derivativeCoeff
updates coeff
too.
Take a copy:
ArrayList<Complex> derivativeCoeff = new ArrayList<>(coeff);
Or, you can remove the first element before taking the copy (obviously checking for emptiness first):
ArrayList<Complex> derivativeCoeff = new ArrayList<>(coeff.subList(1, coeff.size()));
Or you can copy and update the elements directly with a stream.
ArrayList<Complex> derivativeCoeff =
IntStream.rangeClosed(1, coeff.size() - 1)
.mapToObj(i -> coeff.get(i).multiply(i))
.collect(Collectors.toCollection(ArrayList::new));
Or even
return
IntStream.rangeClosed(1, coeff.size() - 1)
.mapToObj(i -> coeff.get(i).multiply(i))
.collect(
Collectors.collectingAndThen(
Collectors.toCollection(ArrayList::new)),
Polynomial::new));
答案2
得分: -1
为了修复这个问题,只需要将
ArrayList<Complex> derivativeCoeff = coeff;
改为
ArrayList<Complex> derivativeCoeff = new ArrayList(coeff);
这是因为Java采用了“按引用传递(call by reference)”的方式,而coeff
是Polynomial对象的一个字段。当你改变Polynomial对象时,会改变coeff
的状态,并且这种改变会在所有引用它的地方都得到反映。
英文:
To fix this, just change
ArrayList<Complex> derivativeCoeff = coeff;
to
ArrayList<Complex> derivativeCoeff = new ArrayList(coeff);
This has happened because Java is call by reference
and coeff
is a field of object Polynomial and when you mutate your Polynomial object it changes the state of coeff
and change is reflected everywhere it was referenced.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论