gpt4 book ai didi

java - 为什么在添加到 HashSet 和 hashCode 匹配时不调用 equals()?

转载 作者:IT老高 更新时间:2023-10-28 21:06:01 30 4
gpt4 key购买 nike

当我运行此代码时,为什么只调用 hashCode() 而不是 equals 方法,而我的 hashCode() 实现生成相同的 HashSet 的两个条目的 hashCode

import java.util.HashSet;

public class Test1 {
public static void main(String[] args) {
Student st=new Student(89);
HashSet st1=new HashSet();
st1.add(st);
st1.add(st);
System.out.println("Ho size="+st1.size());
}
}
class Student{
private int name;
private int ID;
public Student(int iD) {
super();
this.ID = iD;
}
@Override
public int hashCode() {
System.out.println("Hello-hashcode");
return ID;
}
@Override
public boolean equals(Object obj) {
System.out.println("Hello-equals");
if(obj instanceof Student){
if(this.ID==((Student)obj).ID){
return true;
}
else{
return false;
}
}
return false;
}
}

这个的输出是:

Hello-hashcode
Hello-hashcode
Ho size=1

最佳答案

哈希集首先检查引用相等性,如果通过,它会跳过 .equals 调用。这是一种优化并且有效,因为 equals 的合约指定如果 a == ba.equals(b)

我附上了下面的源代码,突出显示了这个检查。

如果你改为添加两个不同的引用元素,你会得到你期望的效果:

    HashSet st1=new HashSet();
st1.add(new Student(89));
st1.add(new Student(89));
System.out.println("Ho size="+st1.size());

结果

$ java Test1
Hello-hashcode
Hello-hashcode
Hello-equals
Ho size=1

这是来自 OpenJDK 7 的源代码,指出了相等优化(来自 HashMap,HashSet 的底层实现):

public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
// v-- HERE
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}

modCount++;
addEntry(hash, key, value, i);
return null;
}

关于java - 为什么在添加到 HashSet 和 hashCode 匹配时不调用 equals()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25331926/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com