为什么在构造函数内部更改了对象中的一个变量?

huangapple go评论85阅读模式
英文:

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&lt;Complex&gt; derivativeCoeff = coeff;

Doesn't copy the list: updating derivativeCoeff updates coeff too.

Take a copy:

ArrayList&lt;Complex&gt; derivativeCoeff = new ArrayList&lt;&gt;(coeff);

Or, you can remove the first element before taking the copy (obviously checking for emptiness first):

ArrayList&lt;Complex&gt; derivativeCoeff = new ArrayList&lt;&gt;(coeff.subList(1, coeff.size()));

Or you can copy and update the elements directly with a stream.

ArrayList&lt;Complex&gt; derivativeCoeff =
    IntStream.rangeClosed(1, coeff.size() - 1)
        .mapToObj(i -&gt; coeff.get(i).multiply(i))
        .collect(Collectors.toCollection(ArrayList::new));

Or even

return
    IntStream.rangeClosed(1, coeff.size() - 1)
        .mapToObj(i -&gt; 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&lt;Complex&gt; derivativeCoeff = coeff;
to
ArrayList&lt;Complex&gt; 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.

huangapple
  • 本文由 发表于 2020年3月16日 00:59:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/60695411.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定