如果两个对象返回相同的hashCode,是不是意味着它们相等?或者我们需要等于防止碰撞?
我可以通过比较hashCodes来实现equals吗?
答案 0 :(得分:19)
如果两个对象具有相同的hashCode,则它们不一定相等。否则你会发现完美的哈希函数。但事实恰恰相反 - 如果对象相等,那么它们必须具有相同的hashCode。
答案 1 :(得分:9)
hashCode 和等于是有关对象的不同信息
考虑类似于哈希码为生日的人,
在那个场景中,你和许多其他人拥有相同的b-day(相同的哈希码),但是你不是同一个人...
答案 2 :(得分:3)
Oracle Docs中所述的hashCode方法是Java中对象的数字表示。此哈希码具有有限的可能值(由可以存储在int中的值表示)。
对于更复杂的类,您很可能会找到两个具有相同哈希码值的不同对象。此外,没有人阻止你在任何课程中这样做。
class Test {
@Override
public int hashCode() {
return 0;
}
}
因此,建议不要通过比较哈希码来实现equals方法。只有在可以保证每个对象都有唯一的哈希码时,才应将它们用于比较。在大多数情况下,您唯一可以肯定的是,如果两个对象使用 o1.equals(o2)相等,则 o1.hashCode()== o2.hashCode()。< / p>
在equals方法中,您可以定义更复杂的逻辑来比较同一类的两个对象。
答案 3 :(得分:3)
如果两个对象返回相同的hashCode,那是不是意味着它们是相等的?
不,这并不意味着。
.dropdown-menu {
margin-left: 10px;
}
.dropdown-menu > li {
padding-left: 10px
}
Object
说明了这一点:
hashCode
的一般合同是:
- 每当在执行Java应用程序期间多次在同一对象上调用它时,
hashCode
方法必须始终如一 如果equals
中没有使用任何信息,则返回相同的整数 对象的比较被修改。 ...- 如果根据
equals(Object)
方法两个对象相等,则必须对两个对象中的每一个调用hashCode
方法 产生相同的整数结果。- 根据
equals(java.lang.Object)
方法,如果两个对象不相等,则不需要调用hashCode
方法 两个对象中的每一个都必须产生不同的整数结果。 ...
请注意突出显示的声明。它明确地对你的问题说“不”。
还有另一种方法来看待这个。
hashCode
会返回int
。int
只能有2个 32 不同的值。a.hashCode() == b.hashCode()
暗示a.equals(b)
,那么在正在运行的Java应用程序中,任何给定时间只能有2个 32 不同(即互不相等)的对象。最后一点显然不正确。实际上,如果你有足够大的堆来容纳64位JVM中的java.lang.Object
的2个 32 实例,那么这显然不是真的。
第三种方法是一些众所周知的例子,其中两个不同的两个字符串具有相同的哈希码。
鉴于您的假设不正确,其后面的推理也是不正确的。
equals
方法。equals
实施hashCode
。您可以使用hashCode
来实现更快的equals
方法,但只有在调用hashCode
两次比比较两个对象更快的情况下才会这样做。通常不是。
答案 4 :(得分:2)
hashCodes是相等的 - &gt;对象可能相同 - &gt;需要进一步比较 hashCodes是不同的 - &gt;对象不相等(如果hashCode实现正确)
这是如何实现equals方法的。首先,检查hashCodes是否相等。如果是,则需要检查类字段以查看它是否代表完全相同的对象。如果hashCodes不同,您可以确定对象不相等。
答案 5 :(得分:2)
如果有hashCode(),为什么Java需要equals()?
Java需要public class And implements Predicate{
private Predicate pred1;
private Predicate pred2;
public And(Predicate p1, Predicate p2){
this.pred1 = p1;
this.pred2 = p2;
}
@Override
public boolean eval(){
return this.pred1.eval() && this.pred2.eval();
}
@Override
public void execute(){
// Not sure of you want to do here
}
}
public class NameIsSet implements Predicate{
private String name;
public NameIsSet (String name){
this.name = name;
}
@Override
public boolean eval(){
return this.name == null || this.name.length = 0;
}
@Override
public void execute(){
// Not sure of you want to do here
}
}
,因为它是通过检查设计者认为是等于测试的一部分的类,字段和其他条件来测试对象相等性的方法。
equals()
的目的是提供主要供哈希表使用的哈希值;虽然它也可以用于其他目的。返回的值基于对象的字段和复合和/或聚合对象的哈希码。该方法没有考虑对象的类或类型。
hashCode()
和equals()
之间的关系是一种含义。
后者由于以下几个原因而不成立:
hashCode()
可以是特定于实现的,在不同的JVM或JVM目标安装上返回不同的值。在同一个JVM中,hashCode()
可以通过先测试已知的哈希码,并且只有在相同的测试实际相等时才能用作平等的廉价前兆;只要相等测试比生成哈希码要昂贵得多。
我可以通过比较hashCodes来实现equals吗?
没有。如上所述,相等的哈希码并不意味着相等的对象。
答案 6 :(得分:1)
有时(很多时候?)你不会!
这些答案并非不真实。但他们并不能讲述整个故事。
一个示例是您正在创建类SomeClass
的对象加载,并且通过递增静态变量nInstanceCount
或其他一些实例,为每个创建的实例提供唯一ID,在构造函数中:
iD = nInstanceCount++;
您的哈希函数可以然后
int hashCode(){
return iD;
}
你的等于 然后
boolean equals( Object obj ){
if( ! ( obj instanceof SomeClass )){
return false;
}
return hashCode() == obj.hashCode();
}
...在这种情况下,你的想法是等于多余的&#34;确实如此:如果所有类都表现得像这样,Java 10(或Java 23)可能会说,啊,让我们摆脱愚蠢的旧equals
,重点是什么? (NB向后兼容性将会出现在窗口之外)。
有两个要点:
您无法创建MAXINT
个SomeClass
个long
个实例。或者......您 可以 ...如果您设置了一个系统来重新分配以前销毁的实例的ID。 ID通常为int
而不是hashCode()
...但这不起作用,因为int
会返回HashMap
。
这些对象中没有一个可以&#34;等于&#34;另一个,因为你已经定义了这个特定类的 equality = identity 。通常这是可取的。它通常会关闭各种可能性......
你的问题的必要含义可能是这两种方法的用途,这些方法以一种相当烦人的方式必须“合作”。在他/她的回答中,Frelling提到了关键点:需要使用哈希码来排序&#34;桶和#34;像HashMap
这样的类。值得一读的是:非常值得设计高效数据的高级数学数据&#34;桶&#34;像hashCode()
这样的类的机制非常可怕。在阅读之后,你可能会(像我一样)对你应该如何以及为什么要费心去实施content.featured == "featured
有一点理解和敬畏!