编辑:准备我的对象以便在HashMap中使用.
在阅读了一下如何生成哈希码之后,我现在很困惑.我的(可能是微不足道的)问题是,当我有一个可以使用的字段时,我应该如何实现hashCode方法?我可以直接使用fiels吗?如果我理解正确的话,hashCode的值在对象的生命周期内不能改变,我只有一个适合这个的ID,但是我已经在其他地方读过,那个人不应该使用ID ...这个怎么样,怎么样一个基于这个(唯一且没有变化)值的hashCode函数会是什么样的?equals方法也仅基于id ..
pol*_*nts 16
如果您的对象是可变的,则可以随时更改其哈希代码.当然,您应该更喜欢不可变对象(Effective Java第2版,第15项:最小化可变性).
以下是来自Effective Java 2nd Edition的hashCodeequals Josh Bloch的哈希码配方,第9项:覆盖时始终覆盖:
int名为的变量中存储一些常量非零值,比如17 result.int哈希码c:
boolean,则计算(f ? 1 : 0)byte, char, short, int,则计算(int) flong,则计算(int) (f ^ (f >>> 32))float,则计算Float.floatToIntBits(f)double,则计算Double.doubleToLongBits(f),然后long如上所述对结果进行散列.equals方法通过递归调用来比较该字段equals,则hashCode在该字段上递归调用.如果该字段的值为null,则返回0.Arrays.hashCode版本1.5中添加的方法之一.c成result如下:result = 31 * result + c;按照原样配方是正确的,即使只有一个字段.只需根据字段的类型执行相应的操作.
请注意,有些库实际上可以为您简化,例如HashCodeBuilder来自Apache Commons Lang,或者只是Arrays.hashCode/deepHashCode来自java.util.Arrays.
这些库允许您简单地编写如下内容:
@Override public int hashCode() {
return Arrays.hashCode(new Object[] {
field1, field2, field3, //...
});
}
Run Code Online (Sandbox Code Playgroud)
下面是使用Apache的共享郎建设者,以促进便利性和可读性的一个更完整的例子equals,hashCode,toString,和compareTo:
import org.apache.commons.lang.builder.*;
public class CustomType implements Comparable<CustomType> {
// constructors, etc
// let's say that the "significant" fields are field1, field2, field3
@Override public String toString() {
return new ToStringBuilder(this)
.append("field1", field1)
.append("field2", field2)
.append("field3", field3)
.toString();
}
@Override public boolean equals(Object o) {
if (o == this) { return true; }
if (!(o instanceof CustomType)) { return false; }
CustomType other = (CustomType) o;
return new EqualsBuilder()
.append(this.field1, other.field1)
.append(this.field2, other.field2)
.append(this.field3, other.field3)
.isEquals();
}
@Override public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(field1)
.append(field2)
.append(field3)
.toHashCode();
}
@Override public int compareTo(CustomType other) {
return new CompareToBuilder()
.append(this.field1, other.field1)
.append(this.field2, other.field2)
.append(this.field3, other.field3)
.toComparison();
}
}
Run Code Online (Sandbox Code Playgroud)
编写这四种方法非常繁琐,并且很难确保所有合同都得到遵守,但幸运的是,图书馆至少可以帮助您轻松完成工作.某些IDE(例如Eclipse)也可以自动为您生成其中一些方法.
equalshashCode时始终覆盖equalstoStringComparable