[COLLECTIONS-406] Improved ListUtils.subtract to O(n) performance. Thanks to Adrian Nistor for reporting and providing a patch.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/trunk@1345644 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Thomas Neidhart 2012-06-03 10:22:04 +00:00
parent eb88ae9669
commit c531834764
2 changed files with 54 additions and 3 deletions

View File

@ -23,6 +23,7 @@ import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.apache.commons.collections.bag.HashBag;
import org.apache.commons.collections.list.FixedSizeList; import org.apache.commons.collections.list.FixedSizeList;
import org.apache.commons.collections.list.LazyList; import org.apache.commons.collections.list.LazyList;
import org.apache.commons.collections.list.PredicatedList; import org.apache.commons.collections.list.PredicatedList;
@ -106,9 +107,12 @@ public class ListUtils {
* @throws NullPointerException if either list is null * @throws NullPointerException if either list is null
*/ */
public static <E> List<E> subtract(final List<E> list1, final List<? extends E> list2) { public static <E> List<E> subtract(final List<E> list1, final List<? extends E> list2) {
final ArrayList<E> result = new ArrayList<E>(list1); final ArrayList<E> result = new ArrayList<E>();
for (E e : list2) { final HashBag<E> bag = new HashBag<E>(list2);
result.remove(e); for (final E e : list1) {
if (!bag.remove(e, 1)) {
result.add(e);
}
} }
return result; return result;
} }

View File

@ -234,6 +234,53 @@ public class TestListUtils extends BulkTest {
} catch(NullPointerException npe) {} // this is what we want } catch(NullPointerException npe) {} // this is what we want
} }
public void testSubtract() {
List<String> list = new ArrayList<String>();
list.add(a);
list.add(b);
list.add(a);
list.add(x);
List<String> sub = new ArrayList<String>();
sub.add(a);
List<String> result = ListUtils.subtract(list, sub);
assertTrue(result.size() == 3);
List<String> expected = new ArrayList<String>();
expected.add(b);
expected.add(a);
expected.add(x);
assertEquals(expected, result);
try {
ListUtils.subtract(list, null);
fail("expecting NullPointerException");
} catch(NullPointerException npe) {} // this is what we want
}
public void testSubtractNullElement() {
List<String> list = new ArrayList<String>();
list.add(a);
list.add(null);
list.add(null);
list.add(x);
List<String> sub = new ArrayList<String>();
sub.add(null);
List<String> result = ListUtils.subtract(list, sub);
assertTrue(result.size() == 3);
List<String> expected = new ArrayList<String>();
expected.add(a);
expected.add(null);
expected.add(x);
assertEquals(expected, result);
}
/** /**
* Tests the <code>indexOf</code> method in <code>ListUtils</code> class.. * Tests the <code>indexOf</code> method in <code>ListUtils</code> class..
*/ */