TreeSet显示错误的输出 [英] TreeSet is showing wrong output
问题描述
在使用树集时,我发现了非常奇特的行为。根据我的理解,这个程序应该打印两个相同的行:
While working with a tree set, I found very peculiar behavior. As per my understanding this program should print two identical lines:
public class TestSet {
static void test(String... args) {
Set<String> s = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
s.addAll(Arrays.asList("a", "b"));
s.removeAll(Arrays.asList(args));
System.out.println(s);
}
public static void main(String[] args) {
test("A");
test("A", "C");
}
}
但奇怪的是打印出来:
[b]
[a, b]
为什么树集的行为如下?
Why is tree set behaving like this?
推荐答案
这是因为使用了SortedSet的比较器用于排序,但removeAll依赖于每个元素的 equals
方法。来自 SortedSet文档:
This happens because a SortedSet’s Comparator is used for sorting, but removeAll relies on the equals
method of each element. From the SortedSet documentation:
请注意,排序集维护的排序(无论是否提供显式比较器)必须与equals 一致排序集是为了正确实现
Set
接口。 (请参阅可比较
界面或比较器
界面,以获得与一致的精确定义。 )这是因为Set
接口是根据等于
操作定义的,但是有序集合执行所有元素使用compareTo
(或比较
)方法进行比较,因此通过此方法认为相同的两个元素来自排序集的立场,相等。排序集的行为定义良好,即使它的排序与equals不一致;它只是不遵守Set
接口的一般合同。
Note that the ordering maintained by a sorted set (whether or not an explicit comparator is provided) must be consistent with equals if the sorted set is to correctly implement the
Set
interface. (See theComparable
interface orComparator
interface for a precise definition of consistent with equals.) This is so because theSet
interface is defined in terms of theequals
operation, but a sorted set performs all element comparisons using itscompareTo
(orcompare
) method, so two elements that are deemed equal by this method are, from the standpoint of the sorted set, equal. The behavior of a sorted set is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of theSet
interface.
可比文档:
当且仅当
e1.compareTo(e2)时,类
与每个C
的自然顺序被认为与equals 一致)== 0e1 $ c $的
e1.equals(e2)
具有相同的布尔值c>和e2
类C
。请注意,null
不是任何类的实例,e.compareTo(null)
应抛出NullPointerException
即使e.equals(null)
返回false
。
The natural ordering for a class
C
is said to be consistent with equals if and only ife1.compareTo(e2) == 0
has the same boolean value ase1.equals(e2)
for everye1
ande2
of classC
. Note thatnull
is not an instance of any class, ande.compareTo(null)
should throw aNullPointerException
even thoughe.equals(null)
returnsfalse
.
强烈建议(尽管不要求)自然排序与equals一致。这是因为没有显式比较器的有序集(和有序映射)在与自然排序与equals不一致的元素(或键)一起使用时表现得奇怪。特别是,这样的有序集(或有序映射)违反了集合(或映射)的一般契约,它是根据等于
方法定义的。
It is strongly recommended (though not required) that natural orderings be consistent with equals. This is so because sorted sets (and sorted maps) without explicit comparators behave "strangely" when they are used with elements (or keys) whose natural ordering is inconsistent with equals. In particular, such a sorted set (or sorted map) violates the general contract for set (or map), which is defined in terms of the equals
method.
总之,你的Set的比较器的行为与元素'等于
的方法不同,导致异常(虽然可预测的行为。
In summary, your Set’s Comparator behaves differently than the elements’ equals
method, causing unusual (though predictable) behavior.
这篇关于TreeSet显示错误的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!