我知道(约定),当equals被覆盖时,我们需要重写哈希码。 为什么我应该考虑用于等同比较的相同字段来计算哈希码? 是否通过避免将太多对象映射到同一个存储桶来提高性能? 即在同一个“日期”上创建的所有对象都会映射到相同的存储桶,并且使用equals()方法检查对象是否存在需要花费时间进行线性比较?重写哈希码时要考虑的数据成员,等于
如果我的上述说法属实,除了性能问题之外,下面的代码还会出现其他潜在问题。这是我们应该使用equals中的相同字段/成员来计算哈希码的唯一原因吗?请分享。谢谢。
class MyClass {
int date;
int pay;
int id;
public boolean equals(Object o) {
//null and same class instance check
MyClass obj = (MyClass) o;
return (date == obj.date && pay == obj.pay && id == obj.id);
}
public int hashCode() {
int hash = 7;
return (31 * hash + date);
}
}
//请原谅语法错误,我不使用ide键入。
***我的本意是用在平等的各个领域,并知道为什么要在哈希代码中使用相同数量的元素,如果只有少数元素被用来
澄清会发生什么: 由于只有使用“日期”计算哈希码,指针检查正确的桶地址(你同意吗?)此外,我得到该桶中的项目列表,集合将迭代检查特定的obj是否存在使用equals。而我对平等的定义是“所有领域必须相同”。有了这个,我相信我的代码工作正常,我只能找到性能问题。请指出我错在哪里。谢谢
你还必须考虑这个要求(在同一本书中的其他地方提及,IIRC)'hashcode()'与** **一致。基本上,这意味着如果'obj1.equals(obj2)',那么'obj1'和'obj2' *必须具有相同的散列值。相反是不正确的。如果'!obj1.equals(obj2)'和它们*具有相同的散列值,那么它实际上并不是错误的,但是基于散列的集合将表现得很差。 – 2014-10-23 06:23:17
@KevinKrumwiede,是的我意识到这一点,我的观点是要明白,如果代码失败的时候:如果'n'成员用于equals()比较,我使用'小于n'成员的散列码,我的代码会破坏还是一些东西。但它不会中断,但会增加将多个对象映射到同一个存储桶的机会,从而降低性能。谢谢。 – 2014-10-23 06:32:02