为什么ArrayDeque没有覆盖equals()和hashCode()方法?

7

编辑:现在只考虑ArrayDeque。(起初我认为LinkedList也没有覆盖这两个方法。)

集合类型ArrayDeque直接使用从Object继承的hashCode和equals方法实现。

为什么它不用包含元素进行哈希和相等性测试来代替,从而覆盖这些方法并进行适当的实现呢?

5个回答

9
LinkedList是一个扩展自AbstractSequentialList的类,而后者继承自AbstractList,这个类确实重写了equalshashCode方法——因此这些实现并非从Object类中继承而来。
另一方面,ArrayDeque似乎没有继承除实现以外的任何东西。它的直接超类(AbstractCollection)没有重写它们。这感觉像是个例外情况,而不是规则——我相信Java中的大多数集合实现会"做正确的事情"。
我不知道ArrayDeque选择不实现相等性的理由,但如果您想比较两个双端队列,可以轻松地将它们转换为列表或数组,然后进行比较。

异常或者疏忽/漏洞。 - T.J. Crowder
@T.J.Crowder: 的确。我们无法轻易地分辨出哪个是哪个 :( (据我所知,文档中没有说明。) - Jon Skeet
1
@devconsole:它没有遵守合同的哪一点?Collection.equals文档包括“Collection接口对于Object.equals的一般约定没有任何规定”和“没有必要这样做(即覆盖equals),而最简单的方法是依赖于Object的实现”。 - Jon Skeet
2
实际上相反是正确的,Deque 明确指出:“Deque 实现通常不定义基于元素的 equals 和 hashCode 方法,而是从 Object 类继承基于标识的版本”。 - devconsole
我写道“比创建列表稍微更高效一些”,因为创建列表总是涉及复制数组,但也会有一些额外的开销。 - Martin Rust
显示剩余5条评论

2

它们被覆盖在AbstractList中,这个类存在于LinkedList继承链中。


对于LinkedList,是的它们被覆盖了。但是对于ArrayDeque,正如Jon所提到的,使用了来自Object的实现。 - Pouria

2
通常情况下,将要被改变的对象实例报告自己与除自己以外的任何东西相等是没有意义的。一些可变集合类型的实例报告自己与其他集合实例相等的主要原因是,代码通常会持有对实例的引用,即使它们“可能”会被改变,但实际上不会。虽然代码可以持有两个ArrayDequeue的引用,以封装曾经或将要放入这些实例中的所有项,并且比较这两个为此目的而保留的ArrayDequeue实例的内容可能是有意义的,但该类型的整个目的是促进项目的推送和弹出;在需要equals检查相同内容的情况下,提取内容到其目的是封装列表的类型中也可能是有意义的。

当你编写单元测试用例,然后assertEquals失败时,这只会让事情稍微有些混乱 :) - Kilokahn

0

0

使用Guava,您可以使用Iterables.elementsEqual方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接