我有以下的单元测试:我创建了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