From c531834764c31d56332b0918d404c3dbbf02ccac Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Sun, 3 Jun 2012 10:22:04 +0000 Subject: [PATCH] [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 --- .../apache/commons/collections/ListUtils.java | 10 ++-- .../commons/collections/TestListUtils.java | 47 +++++++++++++++++++ 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/apache/commons/collections/ListUtils.java b/src/main/java/org/apache/commons/collections/ListUtils.java index 4fd5fb779..dfb4be56a 100644 --- a/src/main/java/org/apache/commons/collections/ListUtils.java +++ b/src/main/java/org/apache/commons/collections/ListUtils.java @@ -23,6 +23,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; +import org.apache.commons.collections.bag.HashBag; import org.apache.commons.collections.list.FixedSizeList; import org.apache.commons.collections.list.LazyList; import org.apache.commons.collections.list.PredicatedList; @@ -106,9 +107,12 @@ public class ListUtils { * @throws NullPointerException if either list is null */ public static List subtract(final List list1, final List list2) { - final ArrayList result = new ArrayList(list1); - for (E e : list2) { - result.remove(e); + final ArrayList result = new ArrayList(); + final HashBag bag = new HashBag(list2); + for (final E e : list1) { + if (!bag.remove(e, 1)) { + result.add(e); + } } return result; } diff --git a/src/test/java/org/apache/commons/collections/TestListUtils.java b/src/test/java/org/apache/commons/collections/TestListUtils.java index 1e1ab0e53..74e070861 100644 --- a/src/test/java/org/apache/commons/collections/TestListUtils.java +++ b/src/test/java/org/apache/commons/collections/TestListUtils.java @@ -234,6 +234,53 @@ public class TestListUtils extends BulkTest { } catch(NullPointerException npe) {} // this is what we want } + public void testSubtract() { + List list = new ArrayList(); + list.add(a); + list.add(b); + list.add(a); + list.add(x); + + List sub = new ArrayList(); + sub.add(a); + + List result = ListUtils.subtract(list, sub); + assertTrue(result.size() == 3); + + List expected = new ArrayList(); + 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 list = new ArrayList(); + list.add(a); + list.add(null); + list.add(null); + list.add(x); + + List sub = new ArrayList(); + sub.add(null); + + List result = ListUtils.subtract(list, sub); + assertTrue(result.size() == 3); + + List expected = new ArrayList(); + expected.add(a); + expected.add(null); + expected.add(x); + + assertEquals(expected, result); + } + /** * Tests the indexOf method in ListUtils class.. */