dme*_*ter 430
最好的实施?这是一个难题,因为它取决于使用模式.
对于几乎所有情况,在Josh Bloch的第8版(第二版)的 Effective Java中提出了合理的良好实现.最好的方法是在那里查找,因为作者解释了为什么这种方法很好.
创建一个int result并指定一个非零值.
对于方法中测试的每个字段 f,通过以下equals()方式计算哈希码c:
boolean:calculate (f ? 0 : 1);byte,char,short或int:计算(int)f;long:calculate (int)(f ^ (f >>> 32));float:calculate Float.floatToIntBits(f);double:计算Double.doubleToLongBits(f)并处理返回值,就像每个long值一样;hashCode()方法的结果或0如果f == null;将哈希值c与result:
result = 37 * result + c
Run Code Online (Sandbox Code Playgroud)返回 result
这应该导致大多数使用情况的哈希值的适当分布.
bac*_*car 135
如果您对dmeister推荐的Effective Java实现感到满意,可以使用库调用而不是自己编译:
@Override
public int hashCode() {
return Objects.hashCode(this.firstName, this.lastName);
}
Run Code Online (Sandbox Code Playgroud)
这需要Guava(com.google.common.base.Objects.hashCode)或Java 7(java.util.Objects.hash)中的标准库,但工作方式相同.
War*_*ior 59
最好使用Eclipse提供的功能,它可以很好地工作,您可以将您的精力和精力投入到开发业务逻辑中.
Chr*_*ski 57
虽然这与Github Android上的文档(Wayback Machine)和我自己的代码相关联,但它通常适用于Java.我的回答是dmeister的答案的扩展,只是代码更容易阅读和理解.
@Override
public int hashCode() {
// Start with a non-zero constant. Prime is preferred
int result = 17;
// Include a hash for each field.
// Primatives
result = 31 * result + (booleanField ? 1 : 0); // 1 bit » 32-bit
result = 31 * result + byteField; // 8 bits » 32-bit
result = 31 * result + charField; // 16 bits » 32-bit
result = 31 * result + shortField; // 16 bits » 32-bit
result = 31 * result + intField; // 32 bits » 32-bit
result = 31 * result + (int)(longField ^ (longField >>> 32)); // 64 bits » 32-bit
result = 31 * result + Float.floatToIntBits(floatField); // 32 bits » 32-bit
long doubleFieldBits = Double.doubleToLongBits(doubleField); // 64 bits (double) » 64-bit (long) » 32-bit (int)
result = 31 * result + (int)(doubleFieldBits ^ (doubleFieldBits >>> 32));
// Objects
result = 31 * result + Arrays.hashCode(arrayField); // var bits » 32-bit
result = 31 * result + referenceField.hashCode(); // var bits » 32-bit (non-nullable)
result = 31 * result + // var bits » 32-bit (nullable)
(nullableReferenceField == null
? 0
: nullableReferenceField.hashCode());
return result;
}
Run Code Online (Sandbox Code Playgroud)
编辑
通常,当您覆盖时hashcode(...),您还要覆盖equals(...).那么对于那些已经或已经实现的人来说equals,这里是我的Github的一个很好的参考...
@Override
public boolean equals(Object o) {
// Optimization (not required).
if (this == o) {
return true;
}
// Return false if the other object has the wrong type, interface, or is null.
if (!(o instanceof MyType)) {
return false;
}
MyType lhs = (MyType) o; // lhs means "left hand side"
// Primitive fields
return booleanField == lhs.booleanField
&& byteField == lhs.byteField
&& charField == lhs.charField
&& shortField == lhs.shortField
&& intField == lhs.intField
&& longField == lhs.longField
&& floatField == lhs.floatField
&& doubleField == lhs.doubleField
// Arrays
&& Arrays.equals(arrayField, lhs.arrayField)
// Objects
&& referenceField.equals(lhs.referenceField)
&& (nullableReferenceField == null
? lhs.nullableReferenceField == null
: nullableReferenceField.equals(lhs.nullableReferenceField));
}
Run Code Online (Sandbox Code Playgroud)
Gre*_*her 17
首先确保正确实现equals.来自IBM DeveloperWorks文章:
- 对称性:对于两个引用,a和b,a.equals(b)当且仅当b.equals(a)
- 自反性:对于所有非空引用,a.equals(a)
- 及物性:如果a.equals(b)和b.equals(c),则a.equals(c)
然后确保它们与hashCode的关系尊重联系人(来自同一篇文章):
- 与hashCode()的一致性:两个相等的对象必须具有相同的hashCode()值
最后,一个好的哈希函数应该努力接近理想的哈希函数.
小智 11
你说的是about8.blogspot.com
如果equals()为两个对象返回true,则hashCode()应该返回相同的值.如果equals()返回false,则hashCode()应返回不同的值
我不能同意你的看法.如果两个对象具有相同的哈希码,则不一定意味着它们是相等的.
如果A等于B,那么A.hashcode必须等于B.hascode
但
如果A.hashcode等于B.hascode,那并不意味着A必须等于B
有一个很好的贯彻实施有效的Java的hashcode()和equals()逻辑的Apache Commons Lang中.Checkout HashCodeBuilder和EqualsBuilder.
如果你使用eclipse,你可以生成equals()和hashCode()使用:
Source - >生成hashCode()和equals().
使用此函数,您可以决定要使用哪些字段进行相等性和哈希码计算,Eclipse会生成相应的方法.
简要说明一下完成其他更详细的答案(根据代码):
如果我考虑如何在Java中创建哈希表(尤其是jGuru FAQ条目)的问题,我认为可以判断哈希码的其他一些标准是:
| 归档时间: |
|
| 查看次数: |
232084 次 |
| 最近记录: |