我正在尝试使用Java中的HashMap检查和删除元素。它的键是我创建的一个名为ClusterKey的类型,它的值是我创建的一个名为ClusterValue的类型。
以下是导致问题的代码:
ClusterKey ck = new ClusterKey(Long.parseLong(split[0].split("=")[1]),
Integer.parseInt(split[1].split("ey")[1]));
if (arg == 0) keys.put(ck, new ClusterValue(index, false));
if (arg == 1) {
if (keys.containsKey(ck)) {
index = keys.get(ck).messageNo;
keys.remove(ck);
}
keys.put(ck, new ClusterValue(index, true));
}
问题是,即使ClusterKey与现有的ClusterKey相同,containsKey()和remove()似乎也没有将它识别为相等。我在类ClusterKey中实现了equals()来覆盖Java的equals()方法,如下所示:
class ClusterKey {
long firstKey;
int secondKey;
public ClusterKey(long firstKey, int secondKey) {
this.firstKey = firstKey;
this.secondKey = secondKey;
} public boolean equals(Object otherKey) {
return this.firstKey == ((ClusterKey) otherKey).firstKey && this.secondKey == ((ClusterKey) otherKey).secondKey;
}
}
所以,我很困惑。非常感谢你的帮助。
此致 丽贝卡
更新:感谢您对我的代码的建议和反馈。我能够通过将hashCode()添加到ClusterKey来解决问题,如下所示:
} public boolean equals(Object otherKey) {
return this.firstKey == ((ClusterKey) otherKey).firstKey && this.secondKey == ((ClusterKey) otherKey).secondKey;
} public int hashCode() {
return (int) firstKey + secondKey;
}
答案 0 :(得分:3)
您需要实施hashCode()
,而不仅仅是equals
,才能使ClusterKey
成为HashMap
中的关键。
具体来说,引用链接的Javadocs:
如果两个对象根据equals(Object)方法相等,那么 必须在两个对象中的每一个上调用hashCode方法 相同的整数结果。
答案 1 :(得分:3)
对于任何启用了Hash的数据结构(例如HashMap
,HashSet
),要正常工作,除hashCode()
方法外,其元素必须覆盖equals()
。原因是哈希码用于标识放置元素(在插入期间)或搜索(在查找期间使用equals()
)的存储区。
如果不覆盖hashCode()
,则使用Object#hashCode()
的默认实现,即使对于您认为等效的对象,也会返回不同的值(equals()
方法返回真的 for)。
这就是你
的原因 hashMap.containsKey(ClusterKey key)
尽管密钥已经存在,呼叫仍然失败。由于哈希码不匹配,HashMap
永远不会在右侧桶中查找密钥。因此,您的equals()
永远不会在这里被调用。