Java 与集合相等和可比

Java 与集合相等和可比,java,equals,comparable,compareto,treeset,Java,Equals,Comparable,Compareto,Treeset,我发布了一些代码,正确地解决了海报上的一个问题。OP希望删除重复项,并将某些特殊项置于列表的顶部。我使用了一个TreeSet和一个特殊的Comparable类,该类包装了他们正在使用的Locale,以实现他们想要的 然后我开始想。。。正如你所做的。。。我是通过从compareTo方法返回0来消除重复,而不是通过从equals实现返回true来消除重复,因为要正确指示集合中的重复(从集合中的重复) 我不反对使用这种技术,但我是否使用了可能被视为未记录的功能?我是否可以放心地假设,今后做这种事情将继

我发布了一些代码,正确地解决了海报上的一个问题。OP希望删除重复项,并将某些特殊项置于列表的顶部。我使用了一个
TreeSet
和一个特殊的
Comparable
类,该类包装了他们正在使用的
Locale
,以实现他们想要的

然后我开始想。。。正如你所做的。。。我是通过从
compareTo
方法返回
0
来消除重复,而不是通过从
equals
实现返回
true
来消除重复,因为要正确指示
集合中的重复(从
集合中的重复)


我不反对使用这种技术,但我是否使用了可能被视为未记录的功能?我是否可以放心地假设,今后做这种事情将继续有效?

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

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

下面是一个示例,它实现了
可比较的
,但与
equals()
不一致:

Set decimals=new HashSet();
小数添加(新的大小数(“42”);
小数添加(新的大小数(“42.0”);
小数添加(新的大小数(“42.00”);
系统输出打印项次(小数);
结尾处的小数有三个值,因为就
equals()
而言,
42.0
42.00
不相等。但是,如果将
HashSet
替换为
TreeSet
,则生成的集合仅包含1项(
42
——这恰好是第一个添加的项),因为在使用比较时,所有项都被视为相等

这表明当使用与
equals()
不一致的类型时,
TreeSet
在某种程度上是“坏的”。它仍然可以正常工作,并且所有的操作都有很好的定义-它只是不遵守
Set
class的约定-如果两个类不
equal()
,它们就不会被视为重复

另见

有趣的是,
ConcurrentSkipListSet
文档中没有这样的注释。@OldCurmudgeon它实际上也在中指定(TreeSet和ConcurrentSkipListSet都实现了该接口)。正如Nurkiewicz先生指出的,这是指定的行为,因此是安全的。不过,我确实同意这是令人惊讶的!
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);