Reputation: 137
Everybody knows that it's better to use an immutable class as key in HashMap
, and if we change object state then the JVM recalculates the hash code for that object.
Can someone make example where after changing the state of an object its hashcode changes? (in runtime)
Upvotes: 0
Views: 2050
Reputation: 393771
Suppose Person
class is mutable, and hashCode
and equals
are computed based on two properties - firstName
and lastName
.
Person p1 = new Person ("John", "Smith");
Person p2 = new Person ("John", "Doe");
Set<Person> persons = new HashSet<Person>();
persons.add (p1);
System.out.println(persons.contains(p2)); // prints false
p2.setLastName("Smith");
System.out.println(persons.contains(p2)); // prints true
And even worse :
Person p1 = new Person ("John", "Smith");
Person p2 = new Person ("John", "Doe");
Set<Person> persons = new HashSet<Person>();
persons.add (p1);
System.out.println(persons.contains(p2)); // prints false
persons.add (p2);
p2.setLastName("Smith");
System.out.println(persons.size()); // prints 2
System.out.println(p1.equals(p2)); // prints true
The HashSet
is broken - it contains two equal instances.
The same example would apply for HashMap
s where the key is Person
.
Upvotes: 0
Reputation: 28568
If you use an object of the following class in a HashMap, and call setState while it's in the map, you will have problems.
Class MutableExample {
private int state;
public void setState(int s) {
state = s;
}
public int hashCode() {
return state;
}
public boolean equals(Object o) {
if (!(o instanceof MutableExample)) {
return false;
}
return ((MutableExample) o).state == state;
}
}
Upvotes: 1
Reputation: 20520
public class Something {
public String blah;
public int hashCode() {
return blah.hashCode();
}
}
Obviously you wouldn't quite code things like this (you'd have a getter and a setter, and the hashCode
would be a little more complicated, and you'd have an equals()
too) but this meets the requirements of your question. If you change the blah
field, then the hash code will change.
Upvotes: 1