Коллекции Java Commons removeAll
CollectionUtils:: removeAll() Коллекции коллекций 3.2.1
Я, должно быть, схожу с ума, потому что кажется, что этот метод делает инверсию того, что утверждают документы:
Удаляет элементы в удалении из коллекции. То есть, этот метод возвращает коллекцию, содержащую все элементы из c, которые не находятся в удалении.
Этот небольшой тест JUnit
@Test
public void testCommonsRemoveAll() throws Exception {
String str1 = "foo";
String str2 = "bar";
String str3 = "qux";
List<String> collection = Arrays.asList(str1, str2, str3);
System.out.println("collection: " + collection);
List<String> remove = Arrays.asList(str1);
System.out.println("remove: " + remove);
Collection result = CollectionUtils.removeAll(collection, remove);
System.out.println("result: " + result);
assertEquals(2, result.size());
}
Сбой при
java.lang.AssertionError: expected: < 2 > но был: < 1 >
и печать
collection: [foo, bar, qux]
remove: [foo]
result: [foo]
Из моего чтения документов я должен ожидать [bar, qux]
. Что я пропустил?
Ответы
Ответ 1
Редактировать 1 января 2014 г. Apache Commons Collections 4.0 был наконец выпущен 21 ноября 2013 г. и содержит исправление для этой проблемы.
Ссылка на CollectionUtils.java
Линии, о которых идет речь (1688 - 1691), с подтверждением, что метод был ранее нарушен:
/*
...
* @since 4.0 (method existed in 3.2 but was completely broken)
*/
public static <E> Collection<E> removeAll(final Collection<E> collection, final Collection<?> remove) {
return ListUtils.removeAll(collection, remove);
}
Оригинальный ответ
Нет, ты не сумасшедший. removeAll()
на самом деле (неправильно) вызывает retainAll()
.
Это ошибка в CollectionUtils
, затрагивающая версию 3.2. Он был исправлен, но только в ветке 4.0.
https://issues.apache.org/jira/browse/COLLECTIONS-349
И в качестве дополнительного доказательства здесь ссылка на исходный код:
http://svn.apache.org/repos/asf/commons/proper/collections/tags/COLLECTIONS_3_2/src/java/org/apache/commons/collections/CollectionUtils.java
Проверьте эту строку:
public static Collection removeAll(Collection collection, Collection remove) {
return ListUtils.retainAll(collection, remove);
}
Угу... сломанный!