两个具有相同哈希码的Java对象不一定相等吗?

我理解为什么为两个相等(通过equals )对象提供相同的哈希码很重要。 但反过来也是如此,如果两个对象具有相同的哈希码,它们必须相等吗? 合同是否仍然有效? 我无法找到可能发生这种情况的示例,因为如果所有参与equals方法的属性也被用于覆盖hashcode方法,那么我们将始终使用相同的对象的哈希码。 请给出意见。

如果两个对象具有相同的哈希码,则它们不一定相等。 否则你会发现完美的哈希函数。 但事实恰恰相反 – 如果对象相等,那么它们必须具有相同的哈希码。

根据Javadoc的说法: http : //download.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode%28%29

如果两个对象根据equals(java.lang.Object)方法不相等,则不需要在两个对象中的每一个上调用hashCode方法必须生成不同的整数结果。 但是,程序员应该知道为不等对象生成不同的整数结果可能会提高哈希表的性能。

编辑:在现实世界中,两个字符串可能具有相同的哈希码。 例如,如果要存储包含长度为10的小写英文字母(如“aaaaaaaaa”,“aaaaaaaa”等)的所有字符串组合,则不能为每个141.167.095.653分配唯一的哈希码。 376种组合,因为Java中的int是32位,因此最多可以有4.294.967.296个不同的值。

hashCode函数的目的是允许将对象快速分区为已知不等于其自身集合之外的所有项的集合。 假设一个有1,000个项目,一个将它们分成十个大致相等大小的集合。 对hashCode一次调用可以快速地将项目识别为不等于900个项目,而不必在任何这些项目上使用equals 。 即使必须使用equals将项目与100个其他项目进行比较,这仍然只是将其与所有1000个项目进行比较的成本的1/10。 实际上,即使在大型集合中, hashCode也经常会消除99.9%或更多的不相等的项目,最多只能检查一小部分。

事实上

 public int hashCode(){ return 1; } 

是一个有效的哈希码实现……但是很糟糕。 会使你所有的哈希表变慢。 但是,是的,您可以使用相同的哈希码来拥有两个不同的对象。 但这不应该是一般情况,真正的实现应该在大多数时间为不同的值提供不同的哈希码。

奇怪的是,NumberFormat是Java基础类的一个例子,它违反了以下建议:

尽可能合理,Object类定义的hashCode方法确实为不同的对象返回不同的整数。

这里有一些代码显示了这一点,至少在我目前在Mac OS X 10.6下运行的Java版本下。

 Numberformat nf = NumberFormat.getNumberInstance(); NumberFormat nf2 = NumberFormat.getNumberInstance(); assert nf != nf2; // passes -- they are different objects assert !nf.equals(nf2); // passes -- they are not equal assert nf.hashCode() != nf2.hashCode(); // fails -- same hash code 

hashCode值取决于实现。 例如, String类根据值实现hashCode()函数。 它的意思是

 String a=new String("b"); String b=new String("b"); 

将具有相同的hashcode但这些是两个不同的对象。 并且a==b将返回false

散列码方法返回整数。 如果整数范围结束,那么两个不同的对象将具有相同的哈希码。 因此,两个不同的对象不必具有相同的哈希码是相等的。

为了certificate,如果两个对象具有相同的hashCode并不意味着它们是相等的

假设您有两个用户定义的类

  class Object1{ private final int hashCode = 21; public int hashCode(){ return hashCode; } public boolean equals(Object obj) { return (this == obj); } } class Object2{ private final int hashCode = 21; public int hashCode(){ return hashCode; } public boolean equals(Object obj) { return (this == obj); } } Object1 object1 = new Object1(); Object2 object2 = new Object2(); Object1 object3 = new Object1(); if(object1.hashCode() == object2.hashCode()){ // return true, because the hashcodes are same } but if(object1.equals(object3)){ // will fail, because two different objects }