2010-11-02 75 views
16

所有,平等之间的HashMap 2

按照equals()我的课的方法,我使用的是私有实例变量HashMap的来比较平等。然而,在比较它们的HashMap变量时,2个不同的对象仍然显示相同。进一步的研究给我带来了链接:Link Here。但是,它只是说HashMap1.equals(HashMap2)不起作用的原因是因为“在没有编写自定义代码的情况下,显然Java的数组无法测试相等性”。

我不明白这个道理。任何人都可以请指导我一个精心设计的理由?

回答

21

对于Java数组类型,equals方法等效于==,因为Java数组“类”不会覆盖Object.equals

如果要“按值”比较数组,则需要使用适当的java.util.Arrays.equals(...)方法,或者自行实施。

如果你的HashHap使用数组作为键或值,这将使HashMap.equals行为奇怪(从你的角度来看)。这就是链接文章所说的。但是,数组语义只有影响HashMap如果您使用数组作为(或在)键或值类中的平等。如果你不这样做,那么equals应该按预期工作。

(该对Map类平等的javadoc是有点麻烦,但他们基本上可以归结为服用两个入口集合,比较它们的大小,然后做s1.containsAll(s2)。当然,这是昂贵的,但它应该适用于正确实现Map接口的所有Map类。)

3

本地Java数组没有.equals()函数。所以如果你的hashmap的值(或者我猜想的键)是数组,HashMap.equals()将会失败。我怀疑它会回退到Object.equals(),它只是检查两个对象是否实际上是同一个对象。

// something like this 
class Object { 
    public boolean equals(Object o) { 
    return this == o; 
    } 
} 

可以通过使用上的一些集装箱的变体,而不是阵列[]上的容器的连续元素回避该问题,作为容器有自己.equals()它调用equals()方法,而不是简单地检查如果他们是相同的参考。对于Collection.equals执行的代码可能看起来像:

public boolean equals(Object o) { 
    // sets never equal lists and visa versa 
    if (o instanceof MyCollectionSubclass) { 
    Iterator myIterator = iterator(); 
    Iterator theirIterator = ((Collection)o).iterator(); 
    while (myIterator.hasNext() && theirIterator.hasNext()) { 
     Object myObj = myIterator.next(); 
     Object theirObj = theirIterator.next(); 
     if (!myObj.equals(theirObj)) { 
     return false; 
     } 
    } 
    // at least one will be false or we wouldn't have left the above while loop 
    return myIterator.hasNext() == theirIterator.hasNext(); 
    } 
    // not our class 
    return false; 
} 

这可能会产生取决于当你调用他们的equals()集合的内容做一个真正的价值比较。

+1

数组从Object继承,并具有与Object相同的实现。 – 2010-11-02 22:28:15

+0

这就是我的想法,尽管我没有费心去查看它。 – 2010-11-02 23:44:38

6

该文章是正确的。只要关键对象和值对象可以使用相同的方法进行比较,就可以使用equals()方法安全地比较HashMap。在文章中,映射值是数组,它没有像预期的那样实现equals()。使用ArrayList反而会解决问题。

2

Java的数组不能平等测试无需编写定制代码

这是说,Java数组不会覆盖Object.equals()的只是一种复杂的方式。因此,如果使用equals()(这是所有集合类的equals方法的作用)进行比较,则会得到“实例平等”,而不是“值相等”。

这实际上只是equals不同方式的特殊情况,取决于它是否被覆盖。