我们将一个String键存储在HashMap中,该HashMap是三个String字段和一个布尔字段的串联.问题是如果分隔符出现在字段值中,则可以创建重复键.
所以为了解决这个问题,根据另一篇文章中的建议,我打算创建一个将用作HashMap键的键类:
class TheKey {
public final String k1;
public final String k2;
public final String k3;
public final boolean k4;
public TheKey(String k1, String k2, String k3, boolean k4) {
this.k1 = k1; this.k2 = k2; this.k3 = k3; this.k4 = k4;
}
public boolean equals(Object o) {
TheKey other = (TheKey) o;
//return true if all four fields are equal
}
public int hashCode() {
return ???;
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
Jon*_*eet 12
只是hashCode和equals应该没问题.hashCode看起来像这样:
public int hashCode() {
int hash = 17;
hash = hash * 31 + k1.hashCode();
hash = hash * 31 + k2.hashCode();
hash = hash * 31 + k3.hashCode();
hash = hash * 31 + k4 ? 0 : 1;
return hash;
}
Run Code Online (Sandbox Code Playgroud)
当然,假设没有一个键可以为空.通常,您可以使用0作为上述等式中空引用的"逻辑"哈希码.需要处理空值的复合相等/哈希码的两种有用方法:
public static boolean equals(Object o1, Object o2) {
if (o1 == o2) {
return true;
}
if (o1 == null || o2 == null) {
return false;
}
return o1.equals(o2);
}
public static boolean hashCode(Object o) {
return o == null ? 0 : o.hashCode();
}
Run Code Online (Sandbox Code Playgroud)
在这个答案开头的哈希算法中使用后一种方法,你最终得到的结果如下:
public int hashCode() {
int hash = 17;
hash = hash * 31 + ObjectUtil.hashCode(k1);
hash = hash * 31 + ObjectUtil.hashCode(k2);
hash = hash * 31 + ObjectUtil.hashCode(k3);
hash = hash * 31 + k4 ? 0 : 1;
return hash;
}
Run Code Online (Sandbox Code Playgroud)