I am new to Java and I am following a class, however in one of the exercises I came up with a doubt when comparing my answer vs. teacher.
Say I have a class that holds as attributes the coefficients of a polynomial and I now want to add two polynomials.
In the teacher solution (method add_1) he makes a copy of the coefficients of both arrays being summed, however from what I understood so far Doubles are immutable, so I assume I don´t need to use a copy, but only address directly (method add_2). I have tested an my values in the array are not mutated, however I wanted to confirm my understanding.
public class Polynomial {
// coefficient at index k belongs to term x^k
// consistency: array is always present and contains at least one number (which
// may be zero)
private double[] coefficients;
// --------------------- constructors
// ----------------------------------------------
// constructor: zero polynomial
public Polynomial() {
coefficients = new double[1];
coefficients[0] = 0;
}
public static Polynomial add_1(Polynomial f, Polynomial g) { // Option 1
double[] f_array = f.getCoefficients();//Do I need this copy?
double[] g_array = f.getCoefficients();//Do I need this copy?
int n = Math.max(f_array.length, g_array.length); // new array needs to be this long
double[] target = new double[n];
// fastest way to do it without if-statements:
for (int k = 0; k < n; k = k + 1) {
target[k] = 0;//Zero vector array
}
for (int k = 0; k < f_array.length; k = k + 1) {
target[k] = target[k] + f_array[k];
}
for (int k = 0; k < g_array.length; k = k + 1) {
target[k] = target[k] + g_array[k];
}
// Turn array into an object
Polynomial p = new Polynomial();
p.setCoefficients(target);
return p;
}
public static Polynomial add_2(Polynomial f, Polynomial g) { // Option 2
int n = Math.max(f_array.length, g_array.length); // new array needs to be this long
double[] target = new double[n];
// fastest way to do it without if-statements:
for (int k = 0; k < n; k = k + 1) {
target[k] = 0;//Zero vector array
}
for (int k = 0; k < f.coefficients.length; k = k + 1) {
target[k] = target[k] + f.coefficients[k];
}
for (int k = 0; k < g.coefficients.length; k = k + 1) {
target[k] = target[k] + g.coefficients[k];
}
// Turn array into an object
Polynomial p = new Polynomial();
p.setCoefficients(target);
return p;
}
// --------------------- setter / getter methods
// -----------------------------------
// setter for coefficients, creates a copy(!) of coefficients and stores it
public void setCoefficients(double[] coefficients) {
this.coefficients = new double[coefficients.length];
for (int k = 0; k < coefficients.length; k = k + 1) {
this.coefficients[k] = coefficients[k];
}
}
// getter for coefficients, returns a copy(!) of the polynomials coefficients
public double[] getCoefficients() {
double[] copy = new double[coefficients.length];
for (int k = 0; k < coefficients.length; k = k + 1) {
copy[k] = coefficients[k];
}
return copy;
}
}
Many thanks
double[] f_array = f.getCoefficients();//Do I need this copy?
This belies a misunderstanding of java.
f.getCoefficients()
doesn't return a double array. That is impossible; java can only return primitives and references. It returns a reference to a double array.
No copy of an array is being made here. The only copies java makes implicitly are of references and primitives; any other copying is something you'd have to do explicitly using e.g. a copy()
or clone()
or Arrays.copyOf
invocation. All that you've done here is make a copy of the reference which doesn't matter. f.getCoefficients()
already returns a copy of the reference.
Let me try to explain with an example:
class Example {
double[] array = new double[10];
public static void main(String[] args) {
Example ex = new Example();
double[] arr = ex.array;
arr[0] = 1;
System.out.println(arr[0]);
System.out.println(ex.array[0]);
ex.array[0] = 2;
System.out.println(arr[0]);
System.out.println(ex.array[0]);
arr = new double[20];
arr[0] = 20;
System.out.println(arr[0]);
System.out.println(ex.array[0]);
}
}
> 1
> 1
> 2
> 2
> 20
> 2
Initially there is only one array, and both ex.array
and arr
are references pointing to this array. arr[0] =
is dereferencing the reference and doing an operation on what you find there, thus, whilst arr
and ex.array
are copies, it's a copy of the same reference, and just like if I make a copy of a treasure map and hand it to you, if you then follow your map, dig down, and steal the treasure, and then later I follow my copy, I find the treasure gone - so it is here: arr[0] = 1
affects the one and only array, and thus printing ex.array[0[]
also shows 1
.
Later, with arr = new double[20]
we first make a new object (new double[20]
) and then assign a reference to this newly created object to arr
, which has no effect on ex.array
. Thus, now, it's like you have a treasure map to a completely different treasure vs. my ex.array
treasure map. Therefore, when you follow your map, dig down, and put a 20
in the box, if I follow my map, I do not see that, hence why the last 2 lines prints 20
and 1
, and not 20
and 20
.