Reputation: 69259
I am trying to copy an ArrayList
, but it seems to be just referencing it and not really copying it.
My code:
List<Column> columns = columnData(referencedField.table);
List<Field> newPath = new ArrayList<>(startPath);
System.out.println("Equals? " + (newPath.equals(startPath)));
startPath
is an ArrayList<Field>
being passed into the function.
Field:
public class Field
{
public String table;
public String column;
public Field(final String table, final String column) {
this.table = table;
this.column = column;
}
@Override
public String toString() {
return "(" + table + ", " + column + ")";
}
@Override
public int hashCode() {
int hash = 3;
hash = 67 * hash + Objects.hashCode(this.table);
hash = 67 * hash + Objects.hashCode(this.column);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Field other = (Field) obj;
if (!Objects.equals(this.table, other.table)) {
return false;
}
if (!Objects.equals(this.column, other.column)) {
return false;
}
return true;
}
}
Now I have read about cloning it, but I am not experienced in it. I am actually wondering if a clone will really create a list of new objects such that they are not being equal anymore, as with same contents the elements would be equal.
So to rephrase, what I want is: To make sure that startPath
and newPath
are not equal and thus not referenced to eachother, as I am using the Lists a recursive function that should add the lists to a map.
Upvotes: 1
Views: 1053
Reputation: 6969
If you are using the overridden equals methods in your classes instead of the referential equality, the copied collection will be equal to the original :-).
There's no way to make this not the case if you have properly overridden the equals methods. No matter how you clone or copy it they will still be the same..
Let me elaborate.
List<Field> newPath = new ArrayList<>(startPath);
will copy the content of startPath
quite well. It calls a native function to copy the internal array so rest assured you objects are deep copied.
The problem is in the way ArrayList
's equals
method works. Well it's not a problem, it's the proper way to do it, but it's the reason you are not getting the in equality in this particular instance.
When you call
newPath.equals(startPath)
it will iterate over the elements and compare all of them using their equals
method. If the element type's equals method is overridden to consider it's state instead of the default referential equality (as is the case with your Field
class) then all the elements in both the lists are equal.
Because their data is equal even though they are not the same objects.
Upvotes: 1
Reputation: 94429
You need to make a deep copy.
List<Field> newPath = new ArrayList<>();
for(Field field: startPath){
newPath.add(field.clone());
}
Upvotes: 3