Add removeIf (#70)

* Add removeIf to SynchronizedCollection, Add mac store files to gitignore

* - added removeIf

* - added removeIf
- added Tests for removeIf

* minor fix

* p tag fix in comments

* Added @since 4.4 javadoc tag
This commit is contained in:
이종현 2019-05-05 23:16:38 +09:00 committed by Gary Gregory
parent ca6851e3ec
commit bd76c28259
25 changed files with 364 additions and 9 deletions

3
.gitignore vendored
View File

@ -15,3 +15,6 @@ site-content
.settings
.classpath
.project
# Mac files
.DS_Store

View File

@ -22,6 +22,7 @@ import java.io.ObjectOutputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Predicate;
import org.apache.commons.collections4.Bag;
import org.apache.commons.collections4.Unmodifiable;
@ -128,6 +129,14 @@ public final class UnmodifiableBag<E>
throw new UnsupportedOperationException();
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(final Collection<?> coll) {
throw new UnsupportedOperationException();

View File

@ -22,6 +22,7 @@ import java.io.ObjectOutputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Predicate;
import org.apache.commons.collections4.SortedBag;
import org.apache.commons.collections4.Unmodifiable;
@ -125,6 +126,14 @@ public final class UnmodifiableSortedBag<E>
throw new UnsupportedOperationException();
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(final Collection<?> coll) {
throw new UnsupportedOperationException();

View File

@ -20,6 +20,8 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Objects;
import java.util.function.Predicate;
import org.apache.commons.collections4.BidiMap;
import org.apache.commons.collections4.MapIterator;
@ -370,6 +372,27 @@ public abstract class AbstractDualBidiMap<K, V> implements BidiMap<K, V> {
return decorated().hashCode();
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(Predicate<? super E> filter) {
if (parent.isEmpty() || Objects.isNull(filter)) {
return false;
}
boolean modified = false;
final Iterator<?> it = iterator();
while (it.hasNext()) {
@SuppressWarnings("unchecked")
final E e = (E) it.next();
if (filter.test(e)) {
it.remove();
modified = true;
}
}
return modified;
}
@Override
public boolean removeAll(final Collection<?> coll) {
if (parent.isEmpty() || coll.isEmpty()) {

View File

@ -19,6 +19,7 @@ package org.apache.commons.collections4.collection;
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Predicate;
/**
* Decorates another <code>Collection</code> to provide additional behaviour.
@ -159,6 +160,14 @@ public abstract class AbstractCollectionDecorator<E>
return decorated().containsAll(coll);
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(final Predicate<? super E> filter) {
return decorated().removeIf(filter);
}
@Override
public boolean removeAll(final Collection<?> coll) {
return decorated().removeAll(coll);

View File

@ -22,6 +22,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.iterators.EmptyIterator;
@ -34,7 +36,7 @@ import org.apache.commons.collections4.list.UnmodifiableList;
* Changes made to this collection will actually be made on the decorated collection.
* Add and remove operations require the use of a pluggable strategy. If no
* strategy is provided then add and remove are unsupported.
*
* </p>
* @param <E> the type of the elements in the collection
* @since 3.0
*/
@ -93,7 +95,7 @@ public class CompositeCollection<E> implements Collection<E>, Serializable {
* Gets the size of this composite collection.
* <p>
* This implementation calls <code>size()</code> on each collection.
*
* </p>
* @return total number of elements in all contained containers
*/
@Override
@ -109,7 +111,7 @@ public class CompositeCollection<E> implements Collection<E>, Serializable {
* Checks whether this composite collection is empty.
* <p>
* This implementation calls <code>isEmpty()</code> on each collection.
*
* </p>
* @return true if all of the contained collections are empty
*/
@Override
@ -126,7 +128,7 @@ public class CompositeCollection<E> implements Collection<E>, Serializable {
* Checks whether this composite collection contains the object.
* <p>
* This implementation calls <code>contains()</code> on each collection.
*
* </p>
* @param obj the object to search for
* @return true if obj is contained in any of the contained collections
*/
@ -144,7 +146,7 @@ public class CompositeCollection<E> implements Collection<E>, Serializable {
* Gets an iterator over all the collections in this composite.
* <p>
* This implementation uses an <code>IteratorChain</code>.
*
* </p>
* @return an <code>IteratorChain</code> instance which supports
* <code>remove()</code>. Iteration occurs over contained collections in
* the order they were added, but this behavior should not be relied upon.
@ -254,7 +256,7 @@ public class CompositeCollection<E> implements Collection<E>, Serializable {
* <p>
* This implementation calls <code>contains()</code> for each element in the
* specified collection.
*
* </p>
* @param coll the collection to check for
* @return true if all elements contained
*/
@ -296,7 +298,7 @@ public class CompositeCollection<E> implements Collection<E>, Serializable {
* Removes the elements in the specified collection from this composite collection.
* <p>
* This implementation calls <code>removeAll</code> on each collection.
*
* </p>
* @param coll the collection to remove
* @return true if the collection was modified
* @throws UnsupportedOperationException if removeAll is unsupported
@ -313,12 +315,34 @@ public class CompositeCollection<E> implements Collection<E>, Serializable {
return changed;
}
/**
* Removes all of the elements of this collection that satisfy the given predicate from this composite collection.
* <p>
* This implementation calls <code>removeIf</code> on each collection.
* </p>
* @param filter a predicate which returns true for elements to be removed
* @return true if the collection was modified
* @throws UnsupportedOperationException if removeIf is unsupported
* @since 4.4
*/
@Override
public boolean removeIf(final Predicate<? super E> filter) {
if (Objects.isNull(filter)) {
return false;
}
boolean changed = false;
for (final Collection<E> item : all) {
changed |= item.removeIf(filter);
}
return changed;
}
/**
* Retains all the elements in the specified collection in this composite collection,
* removing all others.
* <p>
* This implementation calls <code>retainAll()</code> on each collection.
*
* </p>
* @param coll the collection to remove
* @return true if the collection was modified
* @throws UnsupportedOperationException if retainAll is unsupported
@ -338,7 +362,7 @@ public class CompositeCollection<E> implements Collection<E>, Serializable {
* Removes all of the elements from this collection .
* <p>
* This implementation calls <code>clear()</code> on each collection.
*
* </p>
* @throws UnsupportedOperationException if clear is unsupported
*/
@Override

View File

@ -18,6 +18,9 @@ package org.apache.commons.collections4.collection;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Objects;
import java.util.function.Predicate;
import org.apache.commons.collections4.MultiMap;
import org.apache.commons.collections4.Transformer;
@ -212,6 +215,28 @@ public class IndexedCollection<K, C> extends AbstractCollectionDecorator<C> {
return removed;
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(final Predicate<? super C> filter) {
if (Objects.isNull(filter)) {
return false;
}
boolean changed = false;
final Iterator<C> it = iterator();
while (it.hasNext()) {
if (filter.test(it.next())) {
it.remove();
changed = true;
}
}
if (changed) {
reindex();
}
return changed;
}
@Override
public boolean removeAll(final Collection<?> coll) {
boolean changed = false;

View File

@ -19,6 +19,7 @@ package org.apache.commons.collections4.collection;
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Predicate;
/**
* Decorates another {@link Collection} to synchronize its behaviour
@ -183,6 +184,16 @@ public class SynchronizedCollection<E> implements Collection<E>, Serializable {
}
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(final Predicate<? super E> filter) {
synchronized (lock) {
return decorated().removeIf(filter);
}
}
@Override
public boolean removeAll(final Collection<?> coll) {
synchronized (lock) {

View File

@ -18,6 +18,7 @@ package org.apache.commons.collections4.collection;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Predicate;
import org.apache.commons.collections4.BoundedCollection;
import org.apache.commons.collections4.Unmodifiable;
@ -138,6 +139,14 @@ public final class UnmodifiableBoundedCollection<E> extends AbstractCollectionDe
throw new UnsupportedOperationException();
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(final Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(final Collection<?> coll) {
throw new UnsupportedOperationException();

View File

@ -18,6 +18,7 @@ package org.apache.commons.collections4.collection;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Predicate;
import org.apache.commons.collections4.Unmodifiable;
import org.apache.commons.collections4.iterators.UnmodifiableIterator;
@ -97,6 +98,14 @@ public final class UnmodifiableCollection<E>
throw new UnsupportedOperationException();
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(final Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(final Collection<?> coll) {
throw new UnsupportedOperationException();

View File

@ -20,6 +20,7 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.function.Predicate;
import org.apache.commons.collections4.BoundedCollection;
import org.apache.commons.collections4.iterators.AbstractListIteratorDecorator;
@ -138,6 +139,14 @@ public class FixedSizeList<E>
throw unsupportedOperationException();
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(Predicate<? super E> filter) {
throw unsupportedOperationException();
}
@Override
public boolean removeAll(final Collection<?> coll) {
throw unsupportedOperationException();

View File

@ -24,6 +24,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import java.util.function.Predicate;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.collections4.iterators.AbstractIteratorDecorator;
@ -242,6 +243,16 @@ public class SetUniqueList<E> extends AbstractSerializableListDecorator<E> {
return result;
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(Predicate<? super E> filter) {
boolean result = super.removeIf(filter);
set.removeIf(filter);
return result;
}
@Override
public boolean removeAll(final Collection<?> coll) {
boolean result = false;

View File

@ -20,6 +20,7 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.function.Predicate;
import org.apache.commons.collections4.Unmodifiable;
import org.apache.commons.collections4.iterators.UnmodifiableIterator;
@ -97,6 +98,14 @@ public final class UnmodifiableList<E>
throw new UnsupportedOperationException();
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(final Collection<?> coll) {
throw new UnsupportedOperationException();

View File

@ -26,6 +26,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.function.Predicate;
import org.apache.commons.collections4.iterators.UnmodifiableIterator;
import org.apache.commons.collections4.iterators.UnmodifiableListIterator;
@ -262,6 +263,14 @@ public class LinkedMap<K, V> extends AbstractLinkedMap<K, V> implements Serializ
throw new UnsupportedOperationException();
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(final Predicate<? super K> filter) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(final Collection<?> coll) {
throw new UnsupportedOperationException();

View File

@ -21,6 +21,7 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import org.apache.commons.collections4.Unmodifiable;
import org.apache.commons.collections4.iterators.AbstractIteratorDecorator;
@ -92,6 +93,14 @@ public final class UnmodifiableEntrySet<K, V>
throw new UnsupportedOperationException();
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(Predicate<? super Map.Entry<K, V>> filter) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(final Collection<?> coll) {
throw new UnsupportedOperationException();

View File

@ -22,6 +22,7 @@ import java.io.ObjectOutputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Predicate;
import org.apache.commons.collections4.MultiSet;
import org.apache.commons.collections4.Unmodifiable;
@ -125,6 +126,14 @@ public final class UnmodifiableMultiSet<E>
throw new UnsupportedOperationException();
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(final Collection<?> coll) {
throw new UnsupportedOperationException();

View File

@ -22,6 +22,7 @@ import java.io.ObjectOutputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.Queue;
import java.util.function.Predicate;
import org.apache.commons.collections4.Unmodifiable;
import org.apache.commons.collections4.iterators.UnmodifiableIterator;
@ -123,6 +124,14 @@ public final class UnmodifiableQueue<E>
throw new UnsupportedOperationException();
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(final Collection<?> coll) {
throw new UnsupportedOperationException();

View File

@ -24,6 +24,8 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Objects;
import java.util.function.Predicate;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.iterators.EmptyIterator;
@ -283,6 +285,21 @@ public class CompositeSet<E> implements Set<E>, Serializable {
return mutator.addAll(this, all, coll);
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(Predicate<? super E> filter) {
if (Objects.isNull(filter)) {
return false;
}
boolean changed = false;
for (final Collection<E> item : all) {
changed |= item.removeIf(filter);
}
return changed;
}
/**
* Removes the elements in the specified collection from this composite set.
* <p>

View File

@ -23,6 +23,8 @@ import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import java.util.Objects;
import java.util.function.Predicate;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.OrderedIterator;
@ -216,6 +218,21 @@ public class ListOrderedSet<E>
return result;
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(final Predicate<? super E> filter) {
if (Objects.isNull(filter)) {
return false;
}
final boolean result = decorated().removeIf(filter);
if (result) {
setOrder.removeIf(filter);
}
return result;
}
@Override
public boolean removeAll(final Collection<?> coll) {
boolean result = false;

View File

@ -21,6 +21,7 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
/**
* Decorates a <code>Map</code> to obtain <code>Set</code> behaviour.
@ -142,6 +143,14 @@ public final class MapBackedSet<E, V> implements Set<E>, Serializable {
return map.size() != size;
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(Predicate<? super E> filter) {
return map.keySet().removeIf(filter);
}
@Override
public boolean removeAll(final Collection<?> coll) {
return map.keySet().removeAll(coll);

View File

@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.NavigableSet;
import java.util.SortedSet;
import java.util.function.Predicate;
import org.apache.commons.collections4.Unmodifiable;
import org.apache.commons.collections4.iterators.UnmodifiableIterator;
@ -94,6 +95,14 @@ public final class UnmodifiableNavigableSet<E>
throw new UnsupportedOperationException();
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(final Collection<?> coll) {
throw new UnsupportedOperationException();

View File

@ -19,6 +19,7 @@ package org.apache.commons.collections4.set;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Predicate;
import org.apache.commons.collections4.Unmodifiable;
import org.apache.commons.collections4.iterators.UnmodifiableIterator;
@ -96,6 +97,14 @@ public final class UnmodifiableSet<E>
throw new UnsupportedOperationException();
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(final Collection<?> coll) {
throw new UnsupportedOperationException();

View File

@ -22,6 +22,7 @@ import java.io.ObjectOutputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.function.Predicate;
import org.apache.commons.collections4.Unmodifiable;
import org.apache.commons.collections4.iterators.UnmodifiableIterator;
@ -96,6 +97,14 @@ public final class UnmodifiableSortedSet<E>
throw new UnsupportedOperationException();
}
/**
* @since 4.4
*/
@Override
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(final Collection<?> coll) {
throw new UnsupportedOperationException();

View File

@ -33,6 +33,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.function.Predicate;
import org.apache.commons.collections4.AbstractObjectTest;
@ -944,6 +945,53 @@ public abstract class AbstractCollectionTest<E> extends AbstractObjectTest {
}
}
/**
* Tests {@link Collection#removeIf(Predicate)}.
* @since 4.4
*/
public void testCollectionRemoveIf() {
if (!isRemoveSupported()) {
return;
}
resetEmpty();
assertTrue("Empty collection removeIf should return false for a predicate that returns only false",
!getCollection().removeIf(e -> false));
verify();
assertTrue("Empty collection removeIf should return false for a predicate that returns only true",
!getCollection().removeIf(e -> true));
verify();
resetFull();
assertTrue("Full collection removeIf should return false for a predicate that returns only false",
!getCollection().removeIf(e -> false));
verify();
assertTrue("Full collection removeIf should return true for a predicate that returns only true",
getCollection().removeIf(e -> true));
getConfirmed().removeIf(e -> true);
verify();
resetFull();
final List<E> elements = Arrays.asList(getFullElements());
final int mid = getFullElements().length / 2;
final E target = elements.get(mid);
final int size = getCollection().size();
final int targetCount = Collections.frequency(elements, target);
final Predicate<E> filter = e -> target.equals((E) e);
assertTrue("Full collection removeIf should work", getCollection().removeIf(filter));
getConfirmed().removeIf(filter);
verify();
assertTrue("Collection should shrink after removeIf", getCollection().size() == size - targetCount);
assertTrue("Collection shouldn't contain removed element", !getCollection().contains(target));
}
/**
* Tests {@link Collection#retainAll(Collection)}.
*/
@ -1158,6 +1206,14 @@ public abstract class AbstractCollectionTest<E> extends AbstractObjectTest {
}
verify();
try {
getCollection().removeIf(e -> true);
fail("removeIf should raise UnsupportedOperationException");
} catch (final UnsupportedOperationException e) {
// expected
}
verify();
try {
getCollection().removeAll(null);
fail("removeAll should raise UnsupportedOperationException");
@ -1248,6 +1304,16 @@ public abstract class AbstractCollectionTest<E> extends AbstractObjectTest {
// expected
}
resetFull();
try {
final Iterator<E> iter = getCollection().iterator();
getCollection().removeIf(e -> false);
iter.next();
fail("next after removeIf should raise ConcurrentModification");
} catch (final ConcurrentModificationException e) {
// expected
}
resetFull();
try {
final Iterator<E> iter = getCollection().iterator();

View File

@ -22,6 +22,7 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.function.Predicate;
import org.junit.Assert;
@ -345,6 +346,28 @@ public class CompositeCollectionTest<E> extends AbstractCollectionTest<E> {
assertTrue(!two.contains("1"));
}
/**
* @since 4.4
*/
@SuppressWarnings("unchecked")
public void testRemoveIf() {
setUpMutatorTest();
one.add((E) "1");
two.add((E) "2");
two.add((E) "1");
// need separate list to remove, as otherwise one clears itself
final Predicate<E> predicate = e -> e == "1";
c.addComposited(one, two);
c.removeIf(predicate);
assertTrue(!c.contains("1"));
assertTrue(!one.contains("1"));
assertTrue(!two.contains("1"));
c.removeIf(null);
assertTrue(!c.contains("1"));
assertTrue(!one.contains("1"));
assertTrue(!two.contains("1"));
}
@SuppressWarnings("unchecked")
public void testRemoveComposited() {
setUpMutatorTest();