【问题标题】:Why AbstractCollection does not implement equals()?为什么 AbstractCollection 不实现 equals()?
【发布时间】:2010-09-25 09:03:51
【问题描述】:

你知道吗:

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

你知道为什么会这样吗?

【问题讨论】:

    标签: java collections hashmap


    【解决方案1】:

    根据Collection#equals() 的约定,Collections 没有通用的 equals() 方法,因此AbstractCollection 无法提供。

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

    【讨论】:

    • 我喜欢你的回答,你说的和我相似,但方式更好。 Values 不是 Set 或 List,但您可以将其视为 Bag。为什么不用包语义实现 equals()?
    • @Motlin :我同意我们的答案是相似的,不幸的是我们在几秒钟内就互相回答了。就包语义而言,可交换的 containsAll() 检查会不幸地破坏 List.equals() 和 Set.equals() 的合同(因为它们本身不再是可交换的)。
    【解决方案2】:

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

    虽然 Collection 接口没有添加 总合同条款 对于 Object.equals,程序员 实现集合接口 “直接”(换句话说,创建一个 是一个集合但不是的类 一个集合或一个列表)必须小心 如果他们选择覆盖 Object.equals。

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

    【讨论】:

    • 很好的答案。也许我会更具体地问另一个问题,为什么 HashMap$Values 不实现 equals() (可能是因为没有人需要它)。我想我会验证 Greg Case 的回答,因为您自己似乎更喜欢它的措辞。
    【解决方案3】:

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

    例如,考虑 TreeSet、LinkedList、Bag 等

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

    【讨论】:

    • 题中提到values()返回的类型是HashMap$Values
    • 对,但它是什么?它是自定义数据结构还是现有数据结构?我猜它是某种迭代器?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 2016-04-21
    相关资源
    最近更新 更多