Java 为什么AbstractCollection不实现equals()?

Java 为什么AbstractCollection不实现equals()?,java,collections,hashmap,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()) = "

你知道吗

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()));
这是由于
AbstractCollection
(其
HashMap$Values
继承自)没有覆盖
#equals()


你知道为什么会这样吗?

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

例如,考虑TeSESET、LIKEDLIST、BACK等


顺便说一句,关于您发布的代码,值返回的内容的实际类型是什么?这应该是一个具有具体实现的子类。。如果你在运行这个代码时地图是空的,那么你可能会遇到一个不考虑两个空集相等的东西。

< P>两个抽象列表和抽象集扩展ActudioCube,它们对它们的相等()方法有不同的行为,这些方法是由接口和。的界面显示:

而集合接口不添加 总承包合同的规定 对于Object.equals,程序员 实现集合接口 “直接”(换句话说,创建一个 类,该类是集合但不是 一套或一份清单)必须小心 如果他们选择覆盖 Object.equals

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

根据的合同,没有用于
集合的通用equals()方法,因此
AbstractCollection
不能提供一个


请注意,
HashMap$Values
既不是一个集合,也不是一个列表,因此它不支持
equals()

我喜欢你的答案,你说了一些类似于我的话,但方式更好。值不是一个集合或列表,但您可以将其视为一个包。为什么不用bag语义实现equals()?@Motlin:我同意我们的答案是相似的,不幸的是,我们在几秒钟之内就回答了。就bag语义而言,一个可交换的containsAll()检查将不幸地破坏List.equals()和Set.equals()的契约(因为它们本身不再是可交换的)。问题提到values()返回的类型是HashMap$ValuesRight,但它是什么?它是自定义数据结构还是现有数据结构?我猜这是某种迭代器?很好的答案。也许我会问另一个更具体的问题,为什么HashMap$Values不实现equals()(可能是因为没有人需要它)。我想我会证实格雷格·凯斯的答案,因为你自己似乎更喜欢它的措辞。
m1.equals(m2) = true
m1.keySet().equals(m2.keySet()) = true
m1.entrySet().equals(m2.entrySet()) = true
m1.values().equals(m2.values()) = false