在 Java 中,一个 Set 不能包含两个唯一的对象,而 List 没有这个限制。Set 中识别唯一对象的机制是什么。很可能它可能是 equals 方法或 hashCode 方法或正在添加的两个对象的实现。有谁知道识别独特对象的实际机制是什么。是equals方法,hashcode方法还是这两种方法或其他方法?
2 回答
这取决于Set
实施。对于HashSet
and LinkedHashSet
,它同时使用equals
andhashCode
方法。对于TreeSet
,它使用自然Comparator
的对象或特定的提供Comparator
。
基本上,Set
javadoc解释了这一点(强调我的):
不包含重复元素的集合。更正式地说,集合不包含一对元素 e1 和 e2 使得 e1.equals(e2),并且最多包含一个 null 元素。正如它的名字所暗示的,这个接口模拟了数学集合抽象。
除了从 Collection 接口继承的那些之外, Set 接口对所有构造函数的合约以及 add、equals 和 hashCode 方法的合约进行了额外的规定。
TreeSet
自实现以来具有另一种行为SortedSet
(此接口扩展了Set
接口)。从它的javadoc(强调我的):
进一步提供对其元素的总排序的 Set。元素使用它们的自然顺序进行排序,或者由通常在排序集创建时提供的比较器进行排序。集合的迭代器将按元素升序遍历集合。)
请注意,如果有序集合要正确实现 Set 接口,则由有序集合维护的顺序(无论是否提供显式比较器)必须与 equals 一致(有关一致的精确定义,请参见 Comparable 接口或 Comparator 接口equals.) 之所以如此,是因为Set 接口是根据 equals 操作定义的,但排序集使用其 compareTo(或 compare)方法执行所有元素比较。
HashSet Source: 似乎元素存储为 a 中的键HashMap
(需要唯一键),并且put
in 中的方法HashMap
检查以下内容:
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
所以它比较了 hash 和 runs equals
。
TreeSet 使用 TreeMap 来支持其数据,而 TreeMapsput
使用比较器。