大家都知道,這是更好地使用不可變類爲重點的HashMap
,如果我們改變對象的狀態,則重新計算JVM的哈希代碼爲對象。更改的hashCode運行
有人可以使其中改變對象的狀態,它的哈希碼更改後的例子嗎? (在運行時)
大家都知道,這是更好地使用不可變類爲重點的HashMap
,如果我們改變對象的狀態,則重新計算JVM的哈希代碼爲對象。更改的hashCode運行
有人可以使其中改變對象的狀態,它的哈希碼更改後的例子嗎? (在運行時)
public class Something {
public String blah;
public int hashCode() {
return blah.hashCode();
}
}
顯然你會不太代碼這樣的事情(你有一個getter和一個setter和hashCode
將是一個更復雜些,並且你有一個equals()
太)但這符合你的問題的要求。如果更改blah
字段,則哈希碼將會更改。
如果您使用下面的類的對象在一個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;
}
}
類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
s,其中關鍵是Person
。
它的工作原理,但如果我不會重載hashCode(),可狀態變化影響返回值(哈希碼)? – zeds 2014-11-22 14:00:32
如果繼承'Object.hashCode()',那麼狀態更改不會影響返回值,因爲返回值僅基於內存中的位置。如果它擴展了一些覆蓋'.hashCode()'的類,那麼它將取決於該類正在做什麼。 – 2014-11-22 14:06:14
原來使用Object.hashCode()更好?爲什麼我們需要在這種情況下重寫hashcode()? – zeds 2014-11-22 14:18:22