[COLLECTIONS-412] Improved performance of CollectionUtils#subtract. Thanks to Adrian Nistor for report and patch.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/trunk@1353111 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Thomas Neidhart 2012-06-23 11:31:54 +00:00
parent 13c8e44e6a
commit cae889f3c0
1 changed files with 18 additions and 4 deletions

View File

@ -28,6 +28,7 @@ import java.util.ListIterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.commons.collections.bag.HashBag;
import org.apache.commons.collections.collection.PredicatedCollection; import org.apache.commons.collections.collection.PredicatedCollection;
import org.apache.commons.collections.collection.SynchronizedCollection; import org.apache.commons.collections.collection.SynchronizedCollection;
import org.apache.commons.collections.collection.TransformedCollection; import org.apache.commons.collections.collection.TransformedCollection;
@ -246,6 +247,12 @@ public class CollectionUtils {
* <i>b</i>. Only the elements of <i>b</i> that satisfy the predicate * <i>b</i>. Only the elements of <i>b</i> that satisfy the predicate
* condition, <i>p</i> are subtracted from <i>a</i>. * condition, <i>p</i> are subtracted from <i>a</i>.
* *
* <p>The cardinality of each element <i>e</i> in the returned {@link Collection}
* that satisfies the predicate condition will be the cardinality of <i>e</i> in <i>a</i>
* minus the cardinality of <i>e</i> in <i>b</i>, or zero, whichever is greater.</p>
* <p>The cardinality of each element <i>e</i> in the returned {@link Collection} that does <b>not</b>
* satisfy the predicate condition will be equal to the cardinality of <i>e</i> in <i>a</i>.</p>
*
* @param a the collection to subtract from, must not be null * @param a the collection to subtract from, must not be null
* @param b the collection to subtract, must not be null * @param b the collection to subtract, must not be null
* @param p the condition used to determine which elements of <i>b</i> are * @param p the condition used to determine which elements of <i>b</i> are
@ -256,12 +263,19 @@ public class CollectionUtils {
* @since 4.0 * @since 4.0
* @see Collection#removeAll * @see Collection#removeAll
*/ */
public static <O> Collection<O> subtract(final Iterable<? extends O> a, final Iterable<? extends O> b, final Predicate<O> p) { public static <O> Collection<O> subtract(final Iterable<? extends O> a,
ArrayList<O> list = new ArrayList<O>(); final Iterable<? extends O> b,
addAll(list, a); final Predicate<O> p) {
final ArrayList<O> list = new ArrayList<O>();
final HashBag<O> bag = new HashBag<O>();
for (O element : b) { for (O element : b) {
if (p.evaluate(element)) { if (p.evaluate(element)) {
list.remove(element); bag.add(element);
}
}
for (O element : a) {
if (!bag.remove(element, 1)) {
list.add(element);
} }
} }
return list; return list;