Java:重写equals方法在查找哈希表的键时不起作用?

Iva*_*van 1 java

我的哈希表看起来像这样:

Hashtable<Mapping, Integer> mappingCount = new Hashtable<Mapping, Integer>();
Run Code Online (Sandbox Code Playgroud)

我想使用这段代码:

if (mappingCount.get(currentMapping) != null)
    mappingCount.put(currentMapping, mappingCount.get(currentMapping) + 1);
else
    mappingCount.put(currentMapping, 1);
Run Code Online (Sandbox Code Playgroud)

为了能够从散列表中获取值,对于类,Mapping我执行了以下操作:

@Override
public boolean equals(Object obj) {
    return ((Mapping)obj).mappingXML.equals(this.mappingXML);
}
Run Code Online (Sandbox Code Playgroud)

但是,由于mappingCount.get(currentMapping)总是导致这种情况不起作用null.为了确保没有错,我做了以下事情:

if (aaa.contains(currentMapping.getMappingXML()))
    System.out.println("found it!");
else
    aaa.add(currentMapping.getMappingXML());
Run Code Online (Sandbox Code Playgroud)

哪里aaaList<String> aaa = new ArrayList<String>().当然,found it是多次打印.我究竟做错了什么?

Rev*_*nzo 9

您还需要覆盖hashCode()方法.

来自JavaDocs:

要成功存储和检索哈希表中的对象,用作键的对象必须实现hashCode方法和equals方法.

原因是Hashtable使用hashCode作为初步测试来查看两个对象是否等于.如果hashCode匹配,则它使用equals来检查是否发生了冲突.

hashCode()的默认实现返回对象的内存地址,对于两个相等的对象,它们的哈希码也必须相等.

另请参阅hashCode()的常规协定.


duf*_*ymo 5

所有正确覆盖equals和hash代码的建议都是正确的; 约书亚布洛赫告诉你如何正确地做到这一点.

但同样重要的要求是地图中的键必须是不可变的.如果您的类可以更改其值,则在将其添加到地图后,equals和hash代码可能会更改; 灾难随之而来.