Collections.unmodifiableCollection()的hashCode和equals方法

13

Collections类有许多静态辅助方法,以提供各种集合类型的只读视图,例如unmodifiableSet()unmodifiableList()等。对于这些视图对象,hashCode()equals()方法将调用转发到基础集合... 但有一个奇怪的例外:unmodifiableCollection()

JavaDoc 明确说明

返回的集合不会将hashCode和equals操作传递到支持的集合中,而是依赖于ObjectequalshashCode方法。如果支持的集合是set或list,则必须这样做以保留这些操作的契约。

我的问题是:这在说什么?如果支持的集合是set或list,我希望其行为与unmodifiableSet()unmodifiableList()一致。那会违反hashCode/equals契约吗?

1个回答

16

从Collection的JavaDoc中可以得知:

Object.equals方法的一般契约规定必须是对称的(换句话说,a.equals(b)当且仅当b.equals(a))。 List.equals和Set.equals的契约规定列表只等于其他列表,集合只等于其他集合。因此,一个实现既不List接口也不Set接口的集合类的自定义equals方法在与任何列表或集合进行比较时必须返回false。(按照同样的逻辑,不可能编写正确实现Set和List接口的类)。

UnmodifiableList是UnmodifiableCollection,但反过来则不一定成立--包装List的UnmodifiableCollection不是UnmodifiableList。 因此,如果将包装相同List a的UnmodifiableCollection与包装相同List a的UnmodifiableList进行比较,则这两个包装器不应相等。 如果只是通过到封装的列表,则它们将相等。


有一种想法是UnmodifiableCollection可以检查其他类型--如果它是一个集合但不是列表或集合,我认为允许比较没有什么害处。这将允许UnmodifiableCollection与其他UnmodifiableCollections以及其他一些情况进行有效的比较。神秘地失败比较是一个令人讨厌的角落陷阱,而这将使“角落”变得更小,同时仍然保持对称性。 - Thomas W

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