等于和可比较集
我在这里发布了一些代码,正确解决了海报的问题。 OP希望删除重复项并将某些特殊项目放在列表顶部。 我使用了一个TreeSet
和一个特殊的Comparable
类,它包含了他们正在使用的Locale
来实现他们想要的东西。
然后我开始思考……正如你所做的那样…我通过从compareTo
方法返回0
来消除重复,而不是从equals
实现返回true
,因为需要做的是正确地指示Set
的重复(从一个Set
的定义 )。
我不反对使用这种技术,但我使用的是什么可能被视为无证件的function ? 我可以安全地假设继续这样做会继续发挥作用吗?
看起来这在TreeSet
JavaDoc (大胆的矿井)中有很好的记录:
请注意,如果要正确实现
Set
接口,则由set维护的排序(无论是否提供显式比较器) 必须与equals一致 。 (请参阅Comparable
或Comparator
以获得与equals一致的精确定义。)这是因为Set
接口是根据equals
操作定义的,但TreeSet
实例使用compareTo
(或compare)方法执行所有元素比较 ,因此从该集合的角度来看,通过这种方法被认为相等的元素是相等的。 集合的行为即使其排序与equals不一致也是明确定义的; 它只是不遵守Set
接口的一般合同 。
下面是一个实现Comparable
但与equals()
不一致的唯一(?)JDK类的示例:
Set decimals = new HashSet (); decimals.add(new BigDecimal("42")); decimals.add(new BigDecimal("42.0")); decimals.add(new BigDecimal("42.00")); System.out.println(decimals);
decimals
有三个值,因为42.0
和42.00
不等于equals()
。 但是如果用TreeSet
替换HashSet
,结果集只包含1个项( 42
– 碰巧是第一个添加的项),因为当使用BigDecimal.compareTo()
进行比较时,它们都被认为是相等的。
这表明当使用与equals()
不一致的类型时, TreeSet
处于“ 破坏 ”的状态。 它仍然正常工作,并且所有操作都是明确定义的 – 它只是不服从Set
类的契约 – 如果两个类不equal()
,它们不被认为是重复的。
也可以看看
- 比较与equals一致意味着什么? 如果我的class级不遵循这个原则,可能会发生什么?