我有一个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)上的相同键。
所以这是我的问题:
这可能吗? Map接口说它使用equals()来比较键是否为空。我没有在任何SomeInterface类中重写equals()。这是否意味着equals方法可能是错误的?
如果上述情况属实,那么如果HashMap实际上是同一个对象而不是副本,我怎么才能让它在equals()上返回true?这是否可以通过说if(object1 == object2)?我早期在Java开发中被告知我应该避免这样做,但我从未发现应该何时使用它。
提前致谢。 :)
答案 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;等于你的方法。他们可能比你自己手工编写代码要好得多。