我有以下的單元測試:我創建了2個不同的我自定義類型變量的對象。我比較它們的散列碼,它們只是返回它們名稱的哈希碼,即String.hashCode()。HashMap對於不同的內容產生相同的hashCode
然後我創建了2個HashSets,每個HashSets都持有一個變量並比較集合的哈希碼。
在這兩種情況下,散列碼與預期不同。
但是,如果我創建一個名稱爲索引,變量爲值的HashMap,斷言失敗,即他們比較相同。這是爲什麼?
使用Oracle Java 1.8。
編輯:我可以添加另一個保證:Assert.assertNotEquals(map1, map2);
也成立。 此外我認爲正確地解釋這樣的句子:
地圖的哈希碼被定義爲的 在地圖的的entrySet()視圖中的每個條目的散列碼的總和。這確保 m1.equals(m2)意味着根據總體合同 Object.hashCode()的要求,任意兩個 映射m1和m2的m1.hashCode()== m2.hashCode()。 從http://docs.oracle.com/javase/7/docs/api/java/util/AbstractMap.html#hashCode%28%29
@Test
public void test() {
// this assertion holds
Assert.assertNotEquals(new Variable("x").hashCode(), new Variable("y").hashCode());
Set<Variable> set1 = new HashSet<>();
set1.add(new Variable("x"));
Set<Variable> set2 = new HashSet<>();
set2.add(new Variable("y"));
// this assertion also holds
Assert.assertNotEquals(set1.hashCode(), set2.hashCode());
HashMap<String, Variable> map1 = new HashMap<>();
map1.put("x", new Variable("x"));
HashMap<String, Variable> map2 = new HashMap<>();
map2.put("y", new Variable("y"));
// why does this assertion fail?
Assert.assertNotEquals(map1.hashCode(), map2.hashCode());
}
兩者下面是類變量的定義。
public class Variable {
private String name;
public Variable(String name) {
this.name = name;
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof Variable))
return false;
return name.equals(((Variable) obj).name);
}
}
爲什麼你認爲散列碼在任何情況下都必須不同? – 2014-10-28 01:12:14
由於第一個斷言成立,我期望第三個斷言成立。同樣的原因爲什麼第二個斷言也成立。 – hooch 2014-10-28 01:13:26
您使用'Variable'的構造函數將傳遞的值賦給'name'嗎? – 2014-10-28 01:18:14