Permalink
Browse files

Fix Iterables.removeIfFromRandomAccessList to handle Lists for which …

…set() throws IAE (for example, if the list disallows duplicate elements).

Fixes Guava issue #1596
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=105826920
  • Loading branch information...
cgdecker authored and cpovirk committed Oct 20, 2015
1 parent bde8152 commit 1a1b97ee1f065d0bc52c91eeeb6407bfaa6cbea1
@@ -423,6 +423,11 @@ public void testRemoveIf_randomAccess() throws Exception {
testCase.testRemoveIf_randomAccess();
}
public void testRemoveIf_randomAccess_notPermittingDuplicates() throws Exception {
com.google.common.collect.IterablesTest testCase = new com.google.common.collect.IterablesTest();
testCase.testRemoveIf_randomAccess_notPermittingDuplicates();
}
public void testRemoveIf_transformedList() throws Exception {
com.google.common.collect.IterablesTest testCase = new com.google.common.collect.IterablesTest();
testCase.testRemoveIf_transformedList();
@@ -16,6 +16,7 @@
package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Iterables.skip;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newLinkedHashSet;
@@ -1036,6 +1037,38 @@ public boolean apply(String s) {
assertEquals(newArrayList("a", "c", "e"), list);
}
public void testRemoveIf_randomAccess_notPermittingDuplicates() {
// https://github.com/google/guava/issues/1596
final List<String> delegate = newArrayList("a", "b", "c", "d", "e");
List<String> uniqueList = Constraints.constrainedList(delegate,
new Constraint<String>() {
@Override
public String checkElement(String element) {
checkArgument(
!delegate.contains(element), "this list does not permit duplicate elements");
return element;
}
});
assertTrue(uniqueList instanceof RandomAccess);
assertTrue(Iterables.removeIf(uniqueList,
new Predicate<String>() {
@Override
public boolean apply(String s) {
return s.equals("b") || s.equals("d") || s.equals("f");
}
}));
assertEquals(newArrayList("a", "c", "e"), uniqueList);
assertFalse(Iterables.removeIf(uniqueList,
new Predicate<String>() {
@Override
public boolean apply(String s) {
return s.equals("x") || s.equals("y") || s.equals("z");
}
}));
assertEquals(newArrayList("a", "c", "e"), uniqueList);
}
public void testRemoveIf_transformedList() {
List<String> list = newArrayList("1", "2", "3", "4", "5");
List<Integer> transformed = Lists.transform(list,
@@ -181,8 +181,10 @@ public static boolean retainAll(Iterable<?> removeFrom, Collection<?> elementsTo
private static <T> boolean removeIfFromRandomAccessList(
List<T> list, Predicate<? super T> predicate) {
// Note: Not all random access lists support set() so we need to deal with
// those that don't and attempt the slower remove() based solution.
// Note: Not all random access lists support set(). Additionally, it's possible
// for a list to reject setting an element, such as when the list does not permit
// duplicate elements. For both of those cases, we need to fall back to a slower
// implementation.
int from = 0;
int to = 0;
@@ -195,6 +197,9 @@ public static boolean retainAll(Iterable<?> removeFrom, Collection<?> elementsTo
} catch (UnsupportedOperationException e) {
slowRemoveIfForRemainingElements(list, predicate, to, from);
return true;
} catch (IllegalArgumentException e) {
slowRemoveIfForRemainingElements(list, predicate, to, from);
return true;
}
}
to++;

0 comments on commit 1a1b97e

Please sign in to comment.