我的课程如下
public class Hash {
int age;
int id;
String name;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Hash other = (Hash) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
在这里我只使用了两个属性name和id来生成.equals方法,但现在我的问题是。什么应该是实现.hashCode()方法的好方法。
两者的优点和缺点是什么?
答案 0 :(得分:3)
计算哈希码的一个重要规则是,您必须仅使用与equals()
实现相关的信息。
由于您未在age
方法中使用equals
,因此在hashCode
中使用它是错误的!推理非常简单:
equals()
将返回true
hashCode()
(在使用age
的实现上)会返回两个不同的值,但是!不意味着您必须使用所有此类信息。有时只使用一个子集就有好处(例如,如果有一个很大的,难以哈希的对象,这不太可能是两个对象之间的唯一区别)。
最原始,最正确的实现方式是:
public int hashCode() {
return 0;
}
它将正确,但非常低效(因为每个对象都会散列到相同的值,显然!)。
答案 1 :(得分:0)
如果不考虑太多,我会使用:apache' s HashCodeBuilder
要使用此类,请按如下方式编写代码:
public class Person {
String name;
int age;
boolean smoker;
...
public int hashCode() {
// you pick a hard-coded, randomly chosen, non-zero, odd number
// ideally different for each class
return new HashCodeBuilder(17, 37).
append(name).
append(age).
append(smoker).
toHashCode();
}
}
回答:只有name
和id
唯一标识该类的每个对象,并且与equal()
进行比较是否一致?如果是,为什么我应该使用三个属性而不是两个?
Check this Hashing it out Article,有点旧但很好的细节。
答案 2 :(得分:0)
我认为如果你的id是唯一的,你应该只使用id字段来生成hashcode。通过这种方式,您将能够通过仅使用id创建对象来从集合中搜索对象。
此外,如果您的ID是唯一的,我们将为不同的对象提供不同的哈希码,以便它们有效。
答案 3 :(得分:0)
哈希码方法的实现取决于您希望如何完成分段 -
@Override public int hashCode() { return this.id % 2 == 0 ? 1 : 2; }
@Override public int hashCode() { return this.age / 10 ; }
关键是,它实际上取决于您的对象在范围内的分布情况(如果对象在存储桶中正确划分,您将获得更好的性能)以及您希望如何进行分组。