0

我有一个 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 开发的早期就被告知我应该避免这样做,但我从来没有发现什么时候应该使用它。

提前致谢。:)

4

5 回答 5

6

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

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

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

于 2010-12-02T12:59:56.157 回答
3

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

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

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

这正是可以创建某种多个条目的原因。您可以创建类的 2 个实例。从您的角度来看,它们是平等的,因为它们包含相同的数据。但它们是不同的。因此,如果您使用这些对象作为 map 的键,您将生成 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);
}
于 2010-12-02T13:11:34.967 回答
0

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

于 2010-12-02T13:02:18.140 回答
0

您必须实现用作 中键的对象的equals()和方法。hashCode()HashMap

请注意,HashMap不仅使用equals(),它还使用hashCode()。您的hashCode()方法必须正确实现以匹配equals()方法的实现。如果这些方法的实现不匹配,您可能会遇到不可预知的问题。

详细要求见类的API文档的描述equals()和说明。hashCode()Object

于 2010-12-02T13:07:25.313 回答
0

仅供参考,您可以让 Eclipse 等 IDE 为您生成 hashCode 和 equals 方法。与您尝试自己手动编码相比,它们可能会做得更好。

于 2010-12-02T16:37:03.197 回答