Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Commons Collections removeAll

CollectionUtils::removeAll() Commons Collections 3.2.1

I must be going crazy, becuase it seems like this method is doing the inverse of what the docs state:

Removes the elements in remove from collection. That is, this method returns a collection containing all the elements in c that are not in remove.

This little JUnit test

@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()); } 

Is failing with

java.lang.AssertionError: expected:<2> but was:<1>

and prints

collection: [foo, bar, qux]  remove: [foo]  result: [foo] 

From my reading of the docs I should expect [bar, qux]. What have I missed?

like image 389
markdsievers Avatar asked Dec 04 '11 01:12

markdsievers


People also ask

Does CollectionUtils isNotEmpty check for NULL?

isNotEmpty() method of CollectionUtils can be used to check if a list is not empty without worrying about null list. So null check is not required to be placed everywhere before checking the size of the list.

What is Java CollectionUtils?

Simply put, the Apache CollectionUtils provides utility methods for common operations which cover a wide range of use cases and helps in avoiding writing boilerplate code. The library targets older JVM releases because currently, similar functionality is provided by the Java 8's Stream API.

What does Listutils partition do?

partition. Returns consecutive sublists of a list, each of the same size (the final list may be smaller).

How do you use CollectionUtils in Java?

MyObject res = CollectionUtils. find(myList, new Predicate<MyObject>() { @Override public boolean evaluate(MyObject o) { return o. getValue() >= 1 && o. getValue() <= 5; } });


1 Answers

Edit January 1, 2014 Apache Commons Collections 4.0 was finally released on November 21, 2013, and contains a fix for this issue.

Link to CollectionUtils.java

Lines in question (1688 - 1691), with acknowledgement the method was previously broken:

/*  ...  * @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); } 

Original Answer

Nope, you're not crazy. removeAll() is actually (incorrectly) calling retainAll().

This is a bug in CollectionUtils, affecting version 3.2. It's been fixed, but only in the 4.0 branch.

https://issues.apache.org/jira/browse/COLLECTIONS-349

And as further proof, here's a link to the source code:

http://svn.apache.org/repos/asf/commons/proper/collections/tags/COLLECTIONS_3_2/src/java/org/apache/commons/collections/CollectionUtils.java

Check out this line:

public static Collection removeAll(Collection collection, Collection remove) {     return ListUtils.retainAll(collection, remove); } 

Yep...broken!

like image 74
逆さま Avatar answered Sep 18 '22 17:09

逆さま