每个人都知道在HashMap
中使用不可变类作为键是更好的,如果我们更改对象状态,那么JVM将重新计算该对象的哈希码。
有人可以在更改对象状态后,其哈希码发生变化吗? (在运行时)
答案 0 :(得分:1)
public class Something {
public String blah;
public int hashCode() {
return blah.hashCode();
}
}
显然你不会完全编写这样的东西(你有一个getter和一个setter,hashCode
会有点复杂,你也有一个equals()
)但这符合您的问题的要求。如果您更改blah
字段,则哈希码将更改。
答案 1 :(得分:1)
如果在HashMap中使用以下类的对象,并在地图中调用setState,则会出现问题。
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;
}
}
答案 2 :(得分:0)
假设Person
类是可变的,hashCode
和equals
是基于两个属性计算的 - firstName
和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
更糟糕的是:
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
HashSet
被破坏 - 它包含两个相等的实例。
相同的示例适用于密钥为HashMap
的{{1}}。