TreeSet 是否可能等于 HashSet 但 HashSet 不等于 TreeSet

64 java collections hashset treeset

我今天接受了采访,接受采访的人对他的陈述感到困惑,询问是否可能TreeSet等于HashSet但不HashSet等于TreeSet。我说“不”,但据他说,答案是“是”。

怎么可能?

Ani*_*wat 71

你的面试官是对的,他们在某些特定情况下没有等价关系。有可能TreeSet可以等于HashSet而不是相反。下面是一个例子:

TreeSet<String> treeSet = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
HashSet<String> hashSet = new HashSet<>();
treeSet.addAll(List.of("A", "b"));
hashSet.addAll(List.of("A", "B"));
System.out.println(hashSet.equals(treeSet)); // false
System.out.println(treeSet.equals(hashSet)); // true
Run Code Online (Sandbox Code Playgroud)

这样做的原因是 aTreeSet使用比较器来确定元素在HashSet使用时是否重复equals

引用TreeSet

请注意,如果要正确实现 Set 接口,则集合维护的排序(无论是否提供显式比较器)必须与 equals 一致


kew*_*wne 19

不违反 equals 或 Set 的约定是不可能的。Java中equals的定义要求对称,即a.equals(b)必须与b.equals(a).

事实上,Set 的文档

如果指定的对象也是一个集合,两个集合的大小相同,并且指定集合的​​每个成员都包含在这个集合中(或者等价地,这个集合的每个成员都包含在指定的集合中),则返回 true。此定义可确保 equals 方法在 set 接口的不同实现中正常工作。

  • equals 的定义确实要求这样做,但这在技术层面上并没有以任何方式强制执行(甚至无法强制执行)。我什至可以创建一个为 equals() 提供随机结果的类。 (6认同)

小智 10

,这在不违反类的equals方法的一般约定的情况下是不可能的Object,这需要对称性,即x.equals(y)当且仅当y.equals(x)

但是,类TreeSetHashSet实现接口的equals契约Set不同。除其他外,该合约要求指定集合的​​每个成员都包含在该集合中。为了确定一个元素是否在集合中,该contains方法被调用,TreeSet使用该方法ComparatorHashSet使用该方法hashCode

最后:

是的,在某些情况下这是可能的。