【发布时间】:2014-10-28 01:07:59
【问题描述】:
我有以下单元测试:我创建了 2 个不同的自定义类型变量的对象。我比较了他们的哈希码,它只是返回他们名字的哈希码,即 String.hashCode()。
然后我创建 2 个 HashSet,每个都包含一个变量并比较集合的哈希码。
正如预期的那样,在这两种情况下,哈希码都不同。
但是,如果我创建一个名称为索引、变量为值的 HashMap,则断言失败,即它们比较相同。这是为什么呢?
使用 Oracle Java 1.8。
编辑:我可以添加另一个保证:Assert.assertNotEquals(map1, map2); 也成立。
此外,我认为我正确地解释了这句话:
地图的哈希码定义为地图的哈希码之和 地图的 entrySet() 视图中的每个条目。这确保了 m1.equals(m2) 意味着 m1.hashCode()==m2.hashCode() 对于任何两个 地图 m1 和 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);
}
}
【问题讨论】:
-
为什么你认为哈希码在任何情况下都必须不同?
-
我希望第三个断言成立,因为第一个断言成立。第二个断言也成立的原因相同。
-
您使用的
Variable的构造函数是否将传递的值分配给name? -
@PM77-1,是的,否则第一个断言会失败。