简体   繁体   English

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

[英]Why AbstractCollection does not implement equals()?

Did you know that : 你知道吗 :

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()));

would output : 输出:

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

This is caused by the fact that AbstractCollection (which HashMap$Values inherits from) does not overrides #equals() . 这是因为AbstractCollectionHashMap$Values继承自)不会覆盖#equals()

Do you have an idea why this is so ? 你知道为什么会这样吗?

Per the contract of Collection#equals() , there is no general-purpose equals() methods for Collection s, and thus AbstractCollection cannot provide one. 每合同Collection#equals() ,没有通用的等于()方法Collection以及由此导致的AbstractCollection不能提供的。

Note that HashMap$Values is neither a Set nor a List, thus the quandary and in a sense the reason it does not support equals() . 请注意, HashMap$Values既不是Set也不是List,因此是窘境,从某种意义上说它不支持equals()

Both AbstractList and AbstractSet extend AbstractCollection, and they have different behaviors for their equals() methods, specified by the interfaces List and Set . AbstractList和AbstractSet都扩展了AbstractCollection,它们的equals()方法具有不同的行为,由接口ListSet指定。 The interface for Collection says: Collection的界面说:

While the Collection interface adds no stipulations to the general contract for the Object.equals, programmers who implement the Collection interface "directly" (in other words, create a class that is a Collection but is not a Set or a List) must exercise care if they choose to override the Object.equals. 虽然Collection接口没有为Object.equals的一般合同添加任何规定,但是“直接”实现Collection接口的程序员(换句话说,创建一个Collection是集合但不是Set或List的类)必须小心如果他们选择覆盖Object.equals。

So AbstractCollection should definitely not override equals(). 所以AbstractCollection绝对不应该重写equals()。 That said, I don't really know why HashMap$Values would not implement equals() itself. 也就是说,我真的不知道为什么HashMap $ Values不会实现equals()本身。

I am not sure if thatt's the official reason, but AbstractCollection avoids adding semantic constraints on potential subclasses. 我不确定这是否是官方原因,但AbstractCollection避免在潜在的子类上添加语义约束。 The semantics of equality are determined by the nature of the concrete inheriting data structure, and in particular based on whether your structure is ordered and whether it allows duplicates. 等式的语义由具体的继承数据结构的性质决定,特别是基于您的结构是否有序以及是否允许重复。

For example, Consider TreeSet, LinkedList, Bag, etc. 例如,考虑TreeSet,LinkedList,Bag等。

BTW, In relation to the code you posted, what's the actual type of whatever is returned by values? 顺便说一下,关于您发布的代码,值返回的实际类型是什么? That should be a subclass with a concrete implementation.. If your map is empty when you run this code, it's possible that you would be ending up with something that does not consider two empty sets equal. 这应该是具有具体实现的子类。如果在运行此代码时映射为空,则可能最终会出现不考虑两个空集相等的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM