Использование как 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]
Что я делаю неправильно? Почему он ведет себя таким образом?
Edit: String::compareToIgnoreCase
является действительным компаратор:
(l, r) -> l.compareToIgnoreCase(r)
Вот Javadoc из RemoveAll () :
Эта реализация определяет, является меньшим из этого множества и указанной коллекции, с помощью вызова метода размера на каждом. Если этот набор содержит меньше элементов, то перебирает реализацию над этим набором, проверяя каждый элемент, возвращенный итератором, в свою очередь, чтобы увидеть, если он содержится в указанной коллекции. Если это так, содержащиеся, он удаляется из этого набора с методом удалить итератор. Если указанная коллекция имеет меньше элементов, то итерация осуществления в течение указанной коллекции, удаляя из этого набора каждого элемента, возвращенный итератором, используя метод удалить это множество.
В вашем втором эксперименте, вы в первом случае Javadoc. Так перебирает «Java», «C ++» и т.д. , и проверяет , если они содержатся в множестве возвращаемого Set.of("PYTHON", "C++")
. Они не так , поэтому они не удаляются. Используйте другой TreeSet , используя тот же компаратор в качестве аргумента, и он должен работать нормально. Использование двух различных реализаций Set, одна с использованием equals()
, а также другую , используя компаратор, это опасная вещь , чтобы сделать действительно.
Обратите внимание , что есть ошибка открыто об этом: [JDK-8180409] TreeSet RemoveAll непоследовательность с String.CASE_INSENSITIVE_ORDER .