Java Set的唯一对象标识

3
在Java中,Set不能包含两个唯一的对象,而List没有这个限制。在Set中,识别唯一对象的机制是什么?最可能是equals方法或hashCode方法的实现,或者是被添加的两个对象的两种方法。有人知道识别唯一对象的真正机制吗?是equals方法、hashCode方法、两种方法还是其他什么东西?
2个回答

6
这取决于Set实现。对于HashSetLinkedHashSet,它们使用equalshashCode方法。对于TreeSet,它使用对象的自然Comparator或特定提供的Comparator。基本上,Set javadoc解释了这一点(重点在于我):“包含不重复元素的集合。更正式地说,集合不包括任何一对元素e1和e2,使得e1.equals(e2),并且最多只有一个null元素。正如其名称所暗示的那样,此接口模拟数学集合抽象。Set接口除了从Collection接口继承的约束条件外,还对所有构造函数以及add、equals和hashCode方法的约束条件进行了进一步的规定。”

TreeSet 有另一种行为,因为它实现了 SortedSet(这个接口扩展了 Set 接口)。从它的 javadoc 中可以看出(重点在于我):

一个进一步为其元素提供总排序的 Set。元素使用它们的自然排序或者通过通常在排序集创建时提供的 Comparator 进行排序。该集合的迭代器将按升序遍历集合中的元素。

请注意,排序集维护的顺序(无论是否提供了显式比较器)必须与 equals 一致,如果排序集要正确地实现 Set 接口(请参阅 Comparable 接口或 Comparator 接口以获得一致的 equals 的精确定义)。这是因为 Set 接口是根据 equals 操作定义的,但排序集使用其 compareTo(或 compare)方法执行所有元素比较。


1

HashSet源码: 似乎元素被存储为 HashMap 中的键(需要唯一的键),并且 HashMap 中的 put 方法会进行以下检查:

if (e.hash == hash && ((k = e.key) == key || key.equals(k)))

所以它比较哈希值并运行equals
TreeSet使用TreeMap支持其数据,而TreeMaps put使用比较器。

这份源代码可能不兼容其他JVM实现,如JRockit或IBM的JVM。 - Luiggi Mendoza

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