java - 为什么不使用自定义比较器从TreeSet中删除,则会删除较大的项集?

标签 java java-8 comparator java-11 treeset

同时使用Java 8和Java 11,将以下 TreeSet String::compareToIgnoreCase 比较器一起考虑:

final Set<String> languages = new TreeSet<>(String::compareToIgnoreCase);
languages.add("java");
languages.add("c++");
languages.add("python");

System.out.println(languages);                 // [c++, java, python]

当我尝试删除TreeSet中存在的确切元素时,它起作用:所有指定的元素均被删除:
languages.removeAll(Arrays.asList("PYTHON", "C++"));

System.out.println(languages);                 // [java]

但是,如果我尝试删除的大于 TreeSet 中存在的,则该调用根本不会删除任何内容(这不是后续调用,而是被调用而不是上面的代码段):
languages.removeAll(Arrays.asList("PYTHON", "C++", "LISP"));

System.out.println(languages);                 // [c++, java, python]

我究竟做错了什么?为什么会这样呢?

编辑:String::compareToIgnoreCase是有效的比较器:
(l, r) -> l.compareToIgnoreCase(r)

最佳答案

这是removeAll()的javadoc:

This implementation determines which is the smaller of this set and the specified collection, by invoking the size method on each. If this set has fewer elements, then the implementation iterates over this set, checking each element returned by the iterator in turn to see if it is contained in the specified collection. If it is so contained, it is removed from this set with the iterator's remove method. If the specified collection has fewer elements, then the implementation iterates over the specified collection, removing from this set each element returned by the iterator, using this set's remove method.



在您的第二个实验中,您遇到的是Javadoc的第一种情况。因此,它将遍历“java”,“c++”等,并检查它们是否包含在Set.of("PYTHON", "C++")返回的Set中。它们不是,因此不会被删除。
使用另一个TreeSet,使用与参数相同的比较器,它应该可以正常工作。
使用两种不同的Set实现,一种使用equals(),另一种使用比较器,确实是一件危险的事情。

请注意,有关此的错误已打开:[JDK-8180409] TreeSet removeAll inconsistent behaviour with String.CASE_INSENSITIVE_ORDER

关于java - 为什么不使用自定义比较器从TreeSet中删除,则会删除较大的项集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59553029/

相关文章:

java - 自定义比较器

java - 如何并行运行任务并在第一个任务失败时等待第二个任务,否则回复并让第二个任务运行

java - 使用正则表达式查找 2 个括号之间的数字

c++ - C++ 中各种自定义比较器函数之间的差异

Java 8 : How to compare all elements of a Set

java - Reduce 为并行流返回不可预测的结果

kotlin - 在Kotlin中使用比较器

java - 使用 java 权限问题运行 docker

java - 弹出菜单没有膨胀

java - 不同类型的单例模式