10

我在这里发布了一些代码,它正确地解决了发布者遇到的问题。OP 希望删除重复项并将某些特殊项目置于列表顶部。我使用了TreeSet一个特殊的Comparable类,它包装了Locale他们正在使用的东西来实现他们想要的东西。

然后我开始思考......就像你一样......我是通过0compareTo方法返回来消除重复项,而不是通过trueequals实现返回来正确指示 a 中的重复项Set(根据 a 的定义Set)。

我不反对使用这种技术,但我是否使用了可能被视为未记录的功能?我可以安全地假设未来做这种事情会继续奏效吗?

4

1 回答 1

21

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

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

下面是唯一(?)JDK 类的示例,该类实现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.042.00就目前而言不相等equals()。但是,如果您替换HashSetTreeSet,则结果集仅包含一项(42- 恰好是添加的第一个),因为在使用 进行比较时,它们都被认为是相等的BigDecimal.compareTo()

这表明TreeSet使用equals(). 它仍然可以正常工作,并且所有操作都定义明确 - 它只是不遵守Set类的约定 - 如果两个类不是equal(),则它们不被视为重复。

也可以看看

于 2012-10-06T16:36:24.950 回答