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, theHashSet` 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?
 
     
     
    