似乎这在(bold mine)的JavaDoc中有很好的记录:TreeSet
请注意,如果要正确实现接口,集合维护的顺序(无论是否提供显式比较器)必须与 equals 一致。Set
(有关与等于一致的精确定义,请参见Comparable
或Comparator
。)之所以如此,是因为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.0
和42.00
就目前而言不相等equals()
。但是,如果您替换HashSet
为TreeSet
,则结果集仅包含一项(42
- 恰好是添加的第一个),因为在使用 进行比较时,它们都被认为是相等的BigDecimal.compareTo()
。
这表明TreeSet
在使用与equals()
. 它仍然可以正常工作,并且所有操作都定义明确 - 它只是不遵守Set
类的约定 - 如果两个类不是equal()
,则它们不被视为重复。
也可以看看