等于和可比较集

时间:2012-10-06 16:25:37

标签: java equals comparable compareto treeset

我发布了一些代码here,正确解决了海报的问题。 OP希望删除重复项并将某些特殊项目放在列表顶部。我使用了TreeSet一个特殊的Comparable类,它包含了他们正在使用的Locale来实现他们想要的目标。

然后我开始思考......正如你所做的那样...我通过从0方法返回compareTo来消除重复,而不是从{{返回true 1}}实现,以便正确指出equals中的副本(来自Set的{​​{3}})。

我不反对使用这种技术但是我使用的是什么可能被视为未记录的功能?我可以安全地假设继续这样做会继续发挥作用吗?

1 个答案:

答案 0 :(得分:18)

JavaDoc of TreeSet(大胆的我的)中,这似乎有很好的记录:

  

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

以下是Comparable实施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
最后

42有三个值,因为就42.0而言,42.00equals()HashSet不相等。但是,如果您将TreeSet替换为42,则结果集只包含1个项目(TreeSet - 碰巧是第一个添加的项目),因为在使用{进行比较时,所有这些项目都被视为相等{3}}

这表明equals()在使用与Set不一致的类型时“已损坏”。它仍然正常工作,并且所有操作都是明确定义的 - 它只是不遵守equal()类的合同 - 如果两个类不是{{1}},则它们不被视为重复。

另见