When I edit an object, which is contained within a HashSet
, the hash of the object changes, but the HashSet
is not updated internally. Therefor, I practically can add the same object twice:
TestObject testObject = new TestObject(1, "hello");
Set<TestObject> set = new HashSet<>();
set.add(testObject);
testObject.number = 2;
set.add(testObject);
set.forEach(System.out::println);
//will print
//{number:2, string:hello}
//{number:2, string:hello}
Full working code example:
import java.util.*;
public class Main {
public static void main(String[] args) {
TestObject testObject = new TestObject(1, "hello");
Set<TestObject> set = new HashSet<>();
// add initial object
set.add(testObject);
// modify object
testObject.number = 2;
testObject.string = "Bye";
// re-add same object
set.add(testObject);
set.forEach(System.out::println);
}
}
class TestObject {
public int number;
public String string;
public TestObject(int number, String string) {
this.number = number;
this.string = string;
}
@Override
public int hashCode() {
return Objects.hash(number, string);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof TestObject)) {
return false;
}
TestObject o = (TestObject) obj;
return number == o.number && string.equals(o.string);
}
@Override
public String toString() {
return "{number:" + number + ", string:" + string + "}";
}
}
This means, after modifying an object which already is contained in a HashSet, the
HashSet` turns unreliable or invalid.
Modifying an object that is somewhere contained in a Set
(probably even without knowing) seems a regular use case to me . And something which I probably already have done a lot.
This throws me back and brings one basic question to me: When or why should I use a HashSet
if it has such a behaviour?