我发布了一些代码here,正确解决了海报的问题。 OP希望删除重复项并将某些特殊项目放在列表顶部。我使用了TreeSet
一个特殊的Comparable
类,它包含了他们正在使用的Locale
来实现他们想要的目标。
然后我开始思考......正如你所做的那样...我通过从0
方法返回compareTo
来消除重复,而不是从{{返回true
1}}实现,以便正确指出equals
中的副本(来自Set
的{{3}})。
我不反对使用这种技术但是我使用的是什么可能被视为未记录的功能?我可以安全地假设继续这样做会继续发挥作用吗?
答案 0 :(得分:18)
在JavaDoc of TreeSet
(大胆的我的)中,这似乎有很好的记录:
请注意,如果要正确实现
Set
接口,则由集合维护的排序(无论是否提供显式比较器)必须与等于一致。 (请参阅Comparable
或Comparator
以获得与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.00
,equals()
和HashSet
不相等。但是,如果您将TreeSet
替换为42
,则结果集只包含1个项目(TreeSet
- 碰巧是第一个添加的项目),因为在使用{进行比较时,所有这些项目都被视为相等{3}}
这表明equals()
在使用与Set
不一致的类型时“已损坏”。它仍然正常工作,并且所有操作都是明确定义的 - 它只是不遵守equal()
类的合同 - 如果两个类不是{{1}},则它们不被视为重复。