我了解为什么对于两个相等(通过equals
)的对象提供相同的哈希码很重要。但是反过来是否也成立,如果两个对象具有相同的哈希码,它们必须相等吗?这个契约仍然有效吗?我找不到一个可能发生这种情况的例子,因为如果所有参与equals方法的属性也被用于覆盖hashcode方法,那么我们将始终使用相同的哈希码来比较相等的对象。请评论。
hashcode
,它们未必相等。换言之,你将会发现完美的哈希函数是不存在的。hashcode
。如果你重写了 equals() 方法,那么必须同时重写 hashCode() 方法。
你只看到了段落中关于 equals
方法的声明,因为他们只是在讨论该方法。请注意上方有 ...
,这表示故意没有写出 hashcode
方法,只展示了 equals
方法。但是,你必须添加 hashcode
方法。 - Petar MinchevhashCode
函数的目的是允许对象快速分成一组已知不等于其它所有项的集合。假设有1000个项,并将它们分成大约相等的十个集合。调用 hashCode
可以快速识别该项与900个项不相等,而无需对这些项中的任何一个使用 equals
。即使必须使用 equals
将该项与100个其他项进行比较,这仍然只有与所有1000个项进行比较的1/10 的成本。实际上,即使在大型集合中,hashCode
通常也会消除99.9% 或更多的不相等项,最多只剩下少数需要检查。hashCode
的值取决于实现方式。例如,String
类实现了 hashCode()
函数并依据其值进行计算。这意味着
String a=new String("b");
String b=new String("b");
两个对象的hashcode
可能相同,但它们是不同的对象。因此,a==b
会返回false
。
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并不意味着它们相等
假设您有两个用户定义的类
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
}
hashcode() 方法为每个对象返回一个唯一的整数 ID。如果一个对象的 hashcode 不同于另一个对象的 hashcode,则无需执行 equals() 方法:您只需要知道这两个对象不相同即可。另一方面,如果 hashcode 相同,则必须执行 equals() 方法以确定值和字段是否相同。
每当两个不同的对象具有相同的哈希码时,我们称之为冲突。冲突并不是什么关键问题,它只意味着在一个单一的桶中有多个对象,因此HashMap查找必须再次查找以找到正确的对象。我从这里找到了这个信息,希望对您有所帮助。https://eclipsesource.com/blogs/2012/09/04/the-3-things-you-should-know-about-hashcode/#:~:text=HashCode%20collisions,to%20find%20the%20right%20object。
哈希码方法返回整数。如果整数范围结束,那么两个不同的对象也将具有相同的哈希码。因此,并不一定两个不同的对象具有相同的哈希码就相等。