问题描述
我们正在将一个String键存储在一个HashMap中,它是三个String字段和一个布尔字段的连接。问题是如果分隔符出现在字段值中,可以创建重复的键。
We are storing a String key in a HashMap that is a concatenation of three String fields and a boolean field. Problem is duplicate keys can be created if the delimiter appears in the field value.
所以要解决这个问题,根据发布,我打算创建一个将被用作HashMap的关键类键:
So to get around this, based on advice in another post, I'm planning on creating a key class which will be used as the HashMap key:
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 ???;
}
}
我的问题是:
- 从hashCode()返回什么值。地图将共计约30个值。在这30个中,有大约10个不同的k1值(一些条目共享相同的k1值)。
- 要将此密钥类存储为HashMap密钥,只需要覆盖equals()和hashCode()方法?还有其他需要吗?
推荐答案
只要hashCode和equals就可以了。 hashCode可能看起来像这样:
Just hashCode and equals should be fine. The hashCode could look something like this:
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;
}
当然,这是假设没有任何键可以为空。通常,您可以使用0作为上述等式中的空引用的逻辑哈希码。需要处理空值的复合相等/哈希码的两个有用的方法:
That's assuming none of the keys can be null, of course. Typically you could use 0 as the "logical" hash code for a null reference in the above equation. Two useful methods for compound equality/hash code which needs to deal with nulls:
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();
}
在此答案开始时,使用后一种方法在散列算法中,您'最终得到以下东西:
Using the latter method in the hash algorithm at the start of this answer, you'd end up with something like:
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;
}
这篇关于HashMap中的复合字符串键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!