与集合相等且可比


问题内容

我在这里张贴了一些代码,可以正确解决发布者遇到的问题。OP希望删除重复项,并将某些特殊项放在列表的顶部。我TreeSet在一个特殊的Comparable类中使用,包装了Locale他们正在使用的类,以实现他们想要的。

然后我开始思考......像你一样......我是通过返回消除重复0compareTo方法,而不是通过返回trueequals实现作为一个需要做的正确指示在重复Set(自定义一个的Set)。

我不反对使用此技术,但我是否使用了可能被视为 未记录的功能 ?我是否可以安全地假设继续进行此类操作会继续有效?


问题答案:

似乎这在(粗体的)JavaDoc中有TreeSet很好的记录:

注意,如果要正确实现接口,则由一个集合(无论是否提供显式比较器)维护的顺序
必须与equals一致Set。(请参见ComparableComparator对于与equals一致的精确定义。)之所以如此,是因为Set接口是根据equals操作定义的,但是
TreeSet
实例使用其compareTo(或compare)方法执行所有元素比较
,因此两个元素被视为相等从集合的角度来看,此方法是相等的。
集合的行为是明确定义的,即使其顺序与equals不一致也是如此; 它只是不能遵守Set接口的一般约定

这是唯一实现Comparable但与不一致的(?)JDK类的示例equals()

Set<BigDecimal> decimals = new HashSet<BigDecimal>();
decimals.add(new BigDecimal("42"));
decimals.add(new BigDecimal("42.0"));
decimals.add(new BigDecimal("42.00"));
System.out.println(decimals);

decimals在最后有三个值,因为4242.0并且42.00是不相等的,只要equals()关注。但是,如果将其替换HashSetTreeSet,则结果集仅包含一项(42-刚好是第一个添加的项),因为使用进行比较时,它们都被认为是相等的BigDecimal.compareTo()

这表明在使用与不一致的类型时TreeSet,这以“ 损坏 ” 的方式出现equals()。它仍然可以正常工作,并且所有操作都定义明确-
只是不遵守Set类的约定-如果两个类不是equal(),则它们不会被视为重复。

也可以看看

  • 比较等于等于是什么意思?如果我的课堂不遵循这一原则,可能会发生什么?