ams*_*ams 31 java eclipse hash hashtable hashmap
Eclipse源菜单有一个"生成hashCode/equals方法",它生成如下所示的函数.
String name;
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
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;
CompanyRole other = (CompanyRole) obj;
if (name == null)
{
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
Run Code Online (Sandbox Code Playgroud)
如果我在生成时选择多个字段hashCode(),equals()Eclipse使用上面显示的相同模式.
我不是哈希函数的专家,我想知道生成的哈希函数是多么"好"?在什么情况下它会崩溃并导致太多碰撞?
sak*_*dar 17
你可以在java.util.ArrayListas中看到hashCode函数的实现
public int hashCode() {
int hashCode = 1;
Iterator<E> i = iterator();
while (i.hasNext()) {
E obj = i.next();
hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
}
return hashCode;
}
Run Code Online (Sandbox Code Playgroud)
这是一个这样的例子,您生成的Eclipse代码遵循类似的实现方式.但是如果你觉得你必须自己实现你的hashCode,那么Joshua Bloch在他着名的书" Effective Java"中给出了一些很好的指导.我将从那本书的第9项中发布那些重要的观点.那些是,
- 在名为result的int变量中存储一些常量非零值,例如17.
对于对象中的每个重要字段f(通过equals方法考虑的每个字段,即),执行以下操作:
一个.计算字段的int哈希码c:
一世.如果该字段是布尔值,则计算(f?1:0).
II.如果字段是byte,char,short或int,则为compute(int)f.
III.如果字段是long,则计算(int)(f ^(f >>> 32)).
IV.如果该字段是浮点数,请计算Float.floatToIntBits(f).
v.如果该字段是double,则计算Double.doubleToLongBits(f),然后在步骤2.a.iii中散列生成的long.
六.如果该字段是一个对象引用,并且该类的equals方法通过递归调用equals来比较该字段,则在该字段上递归调用hashCode.如果需要更复杂的比较,则为该字段计算"规范表示"并在规范表示上调用hashCode.如果该字段的值为null,则返回0(或其他一些常量,但0是传统的)
七.如果该字段是数组,则将其视为每个元素都是单独的字段.也就是说,通过递归地应用这些规则来计算每个重要元素的哈希码,并且每步骤2.b组合这些值.如果数组字段中的每个元素都很重要,则可以使用版本1.5中添加的Arrays.hashCode方法之一.
湾 将步骤2.a中计算的哈希码c组合到结果中,如下所示:
Run Code Online (Sandbox Code Playgroud)result = 31 * result + c;返回结果.
编写完hashCode方法后,请问自己,相等的实例是否具有相同的哈希码.编写单元测试以验证您的直觉!如果相等的实例具有不相等的哈希码,请弄清楚原因并解决问题.
Java语言设计者和Eclipse似乎遵循我想的类似指南.快乐的编码.干杯.
lef*_*bit 13
从Java 7开始,您可以使用java.util.Objects简短而优雅的方法:
class Foo {
private String name;
private String id;
@Override
public int hashCode() {
return Objects.hash(name,id);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Foo) {
Foo right = (Foo) obj;
return Objects.equals(name,right.name) && Objects.equals(id,right.id);
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13367 次 |
| 最近记录: |