为什么AbstractCollection没有实现equals()?

时间:2008-12-04 17:12:34

标签: java collections hashmap

你知道吗:

Map<Object,Object> m1 = new HashMap<Object, Object>();
Map<Object,Object> m2 = new HashMap<Object, Object>();
System.out.println("m1.equals(m2) = "+m1.equals(m2));
System.out.println("m1.keySet().equals(m2.keySet()) = "
            +m1.keySet().equals(m2.keySet()));
System.out.println("m1.entrySet().equals(m2.entrySet()) = "
            +m1.entrySet().equals(m2.entrySet()));
System.out.println("m1.values().equals(m2.values()) = "
            +m1.values().equals(m2.values()));

会输出:

m1.equals(m2) = true
m1.keySet().equals(m2.keySet()) = true
m1.entrySet().equals(m2.entrySet()) = true
m1.values().equals(m2.values()) = false

这是因为AbstractCollectionHashMap$Values继承)不会覆盖#equals()

你知道为什么会这样吗?

3 个答案:

答案 0 :(得分:6)

根据Collection#equals()的合同,Collection没有通用的equals()方法,因此AbstractCollection无法提供。{/ p>

请注意HashMap$Values既不是Set也不是List,因此是窘境,从某种意义上说它不支持equals()

答案 1 :(得分:4)

AbstractList和AbstractSet都扩展了AbstractCollection,它们的equals()方法有不同的行为,由接口ListSet指定。 Collection的界面说:

  

虽然Collection界面没有添加   对一般合同的规定   对于Object.equals,程序员   实现Collection接口   “直接”(换句话说,创造一个   作为集合的类,但不是   集合或列表必须小心谨慎   如果他们选择覆盖   的Object.Equals。

所以AbstractCollection绝对不应该重写equals()。也就是说,我真的不知道为什么HashMap $ Values不会实现equals()本身。

答案 2 :(得分:0)

我不确定这是否是官方原因,但AbstractCollection避免在潜在的子类上添加语义约束。平等的语义由具体的继承数据结构的性质决定,特别是基于您的结构是否有序以及是否允许重复。

例如,考虑TreeSet,LinkedList,Bag等

顺便说一下,关于您发布的代码,值返回的实际类型是什么?这应该是具有具体实现的子类。如果在运行此代码时映射为空,则可能最终会出现不考虑两个空集相等的内容。