我注意到在hashCode()
的示例中,每个人都在hashCode()
方法定义中使用相同的字段来调用hashCode()
。
为什么我必须为类的每个成员调用/初始化hashCode()
方法,因为哈希代码用于查找对象位置(如果我错了,请纠正我)?
那么,在hashCode()
方法定义中调用hashCode()
的目的是什么呢。
例如:
public int hashCode() {
final int seed = 37;
int result = 1;
result = seed * result + ((name == null) ? 0 : name.hashCode());
result = seed * result + age;
result = seed * result + marks;
return result;
}
这里有两个字段age
和name
。第4行name.hashCode()
的目的是什么。
hashCode
方法由HashMap
和HashSet
等集合使用,以快速检索对象实例的方式分发对象实例(时间复杂度为O(1)
)。实现的hashCode
方法越好,当与对象的实例一起使用时,这些集合的效率就越高。一个实现良好的hashCode
方法将尽可能地限制获得哈希冲突的概率,换句话说,它将限制为两个不同对象的实例获得相同哈希代码的可能性。
知道了这一点,如果我们从hashCode
的实现中删除第4行,那么我们将拥有具有相同age
和marks
的对象的所有实例,这些实例将具有相同的结果哈希代码,无论name
的值是多少,因此获得哈希冲突的概率很高,这是不需要的,如上所述。
因此,由于hashCode
返回一个32
位整数,而name
显然是String
(至少不是基元类型),我们对其调用hashCode()
以获得String
的int
表示,以便以某种方式将其值添加到生成的哈希码中。正因为如此,具有相同age
和marks
的2个对象实例不一定具有相同的哈希代码,因此哈希冲突的风险是有限的,这正是我们所期望的。
我认为这个问题的一个更通用的形式已经被问到了——
hashCode方法的最佳实现
为了总结您的问题,"name"是一个String对象,"age"是一种int文字。种子值通常是一个素数。