你能解释一下这个Java哈希映射键冲突吗?

时间:2010-12-02 12:55:20

标签: java hashmap collision

我有一个HashMap并按以下方式使用:

HashMap<SomeInterface, UniqueObject> m_map;

UniqueObject getUniqueObject(SomeInterface keyObject)
{
     if (m_map.containsKey(keyObject))
     {
         return m_map.get(keyObject);
     }
     else
     {
         return makeUniqueObjectFor(keyObject);
     }
}

我的问题是我看到不同类的多个对象匹配m_map.containsKey(keyObject)上的相同键。

所以这是我的问题:

  1. 这可能吗? Map接口说它使用equals()来比较键是否为空。我没有在任何SomeInterface类中重写equals()。这是否意味着equals方法可能是错误的?

  2. 如果上述情况属实,那么如果HashMap实际上是同一个对象而不是副本,我怎么才能让它在equals()上返回true?这是否可以通过说if(object1 == object2)?我早期在Java开发中被告知我应该避免这样做,但我从未发现应该何时使用它。

  3. 提前致谢。 :)

5 个答案:

答案 0 :(得分:6)

我强烈怀疑你误诊了这个问题。如果你没有在任何地方覆盖equals(并且你没有继承任何覆盖equals的其他内容)那么你应该确实有“身份”行为。

说实话,我听到并非如此,我会感到震惊。

如果您可以制作一个简短但完整的程序来演示问题,那么这会让您更容易调查 - 但目前,我绝对仔细检查您对看到不同的怀疑对象被视为等键。

答案 1 :(得分:3)

equals()的默认实现是在java.lang.Object中完成的:

public boolean equals(Object obj) {
return (this == obj);
}

默认情况下,其他方法hashCode();会返回对该对象的某种引用。即两者都是默认的唯一。 Equals仅对同一对象返回true,hashCode()对于每个对象都不同。

这正是可以创建某种多条目的原因。您可以创建2个类的实例。从您的角度来看,它们是相同的,因为它们包含相同的数据。但他们是不同的。因此,如果您使用这些对象作为地图的键,则您将生成2个条目。如果你想避免这个实现equals和你的类的hashCode。

这种实现有时非常冗长。来自Jakarta项目的HashCodeBuilder和EqualsBuilder可能对您有所帮助。这是一个例子:

@Override
public int hashCode() {
    return HashCodeBuilder.reflectionHashCode(this);
}

@Override
public boolean equals(Object other) {
    return EqualsBuilder.reflectionEquals(this, other);
}

@Override
public String toString() {
    return ToStringBuilder.reflectionToString(this);
}

答案 2 :(得分:0)

您需要确保为要存储在HashMap中的所有对象实现.equals()和.hashCode()方法。没有它会引发各种各样的问题。

答案 3 :(得分:0)

您必须实施equals()中用作关键字的对象的hashCode()HashMap方法。

请注意,HashMap不仅使用equals(),还使用hashCode()。必须正确实施hashCode()方法才能匹配equals()方法的实现。如果这些方法的实现不匹配,则可能会出现不可预测的问题。

有关详细要求,请参阅课程equals()的API文档中的hashCode()Object说明。

答案 4 :(得分:0)

仅供参考,您可以使用Eclipse等IDE生成hashCode&amp;等于你的方法。他们可能比你自己手工编写代码要好得多。