Reputation: 1714
I have an assignment I am working on where I have two classes.
Class A is called Points. It contains data for a 2D coordinate, and additional data associated to that specific point.
Class B is called Particles. It contains an array of objects of class A as well as some additional information.
I have a list of Particles. At initialization, all Particle objects contain an identical array of Points.
If I then change the value of the first position in the Points array in any Particle, I then see that all other Particles have mirrored this change. This is not the bahaviour I want. Instead, I want any changes in any Particle to be unique to that object.
public static class Particle{
public double[][] current = new double[NC][2];
public double[][] pBest = new double[NC][2];
public double[][] vel = new double[NC][2];
public Points[] points = new Points[array.length];
public double pbestfitness = 0.0;
public Particle(){
}
//standard get/set methods here
}
public static class Points{
public int x;
public int y;
public double centroidx;
public double centroidy;
public Points(){
this.x = -1;
this.y = -1;
this.centroidx = -1;
this.centroidy = -1;
}
public int getx(){
return x;
}
public void setx(int a){
x = a;
}
public int gety(){
return y;
}
public void sety(int a){
y = a;
}
public double getcx(){
return centroidx;
}
public void setcx(double a){
centroidx = a;
}
public double getcy(){
return centroidy;
}
public void setcy(double a){
centroidy = a;
}
}
initialization:
for(int i = 0; i < NP; i++){
p = new Particle();
initbest = new double[NC][2];
points = new Points[array.length];
points = array.clone();
for(int j = 0; j < NC; j++){
x = minx + r.nextInt(maxx - minx + 1);
y = miny + r.nextInt(maxy - miny + 1);
p.setCentroid(j, x, y);
initbest[j][0] = x;
initbest[j][1] = y;
}
p.setpBest(initbest);
p.setVel(initV);
p.points = points;
particles.add(p);
}
I thought that the issue was that I was copying each array of type A by address location rather than value, so I tried using System.arraycopy, and Arrays.copyOf() as well as array.clone, but none of them worked.
Here is code where I make a change to one object, but the change is mirrored in all objects:
particles.get(i).points[j].centroidx = particles.get(i).current[closest][0];
particles.get(i).points[j].centroidy = particles.get(i).current[closest][1];
The idea is basically I'm taking a set of point, adding a bunch of centroids, then finding which centroid is closest to each point and associating that point to that centroid. I run this with a set number of random starting positions, hence why I need to have a set number of copies of the starting positions represented by particles. I have ensured that the calculation for finding the closest centroid works using a testing data set of a low number of set points and centroids.
What happens after I complete an iteration of the first particle is that all the other particles are changed, when I have explicitly stated that the centroids of just the first particle is being changed. After the end of the first iteration of all particles is completed, all particles carry identical points arrays with centroids equivalent to the last copy that was changed. instead of unique points arrays with centroid data associated with that particle.
So the first particle will have a list of points with centroids that are not found to be a member of that particle. Instead, it holds the centroid data of the last particle of the previous iteration.
Upvotes: 0
Views: 148
Reputation: 13123
I have a couple of suggestions.
First, when you describe a problem for which you provide code, refer to the variables/arrays/whatever with the names they have in the code. I don't know what you mean by A and B, and don't intend to dig through the code enough to guess, only to be wrong.
Second, if changing the data in one place automatically shows up in the other, then you almost certainly have a reference to the same object in the two places. If you do this:
A a = new A();
B b = new B();
b.setA(a);
array1[0] = a;
array2[0] = b;
then a change to a
will be reflected in the object in both array1 and array2.
To prevent that, you can create an object of type A that is a copy of a, and put THAT into b before putting b into array2. Look up information on the Object.clone() method.
Upvotes: 1
Reputation: 751
All the Point objects with same index reference the same object. So when you change one of them, all the other objects with the same index in all the arrays will change as well. You must make sure that on initialization you make a depp copy of all the Point objects. A deep copy means that the information (in fields) is all the same, but they refer to different objects (You must make a deep copy of the fields too). Arrays.copyOf will not help you because it will create a shallow copy (The points at the same index will refer to the same object.) You need to implement the clone method on point that will create a deep copy of the point. Then during initialization, just call point.clone(). See What is the difference between a deep copy and a shallow copy?.
Upvotes: 2