[COLLECTIONS-551] Move forAllButLastDo methods, add unmodifiableIterable.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/trunk@1683897 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
5214f66618
commit
6c8caea331
|
@ -708,10 +708,12 @@ public class CollectionUtils {
|
|||
* @param closure the closure to perform, may be null
|
||||
* @return the last element in the collection, or null if either collection or closure is null
|
||||
* @since 4.0
|
||||
* @deprecated since 4.1, use {@link IterableUtils#applyForAllButLast(Iterable, Closure)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static <T, C extends Closure<? super T>> T forAllButLastDo(final Iterable<T> collection,
|
||||
final C closure) {
|
||||
return collection != null && closure != null ? forAllButLastDo(collection.iterator(), closure) : null;
|
||||
return closure != null ? IterableUtils.applyForAllButLast(collection, closure) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -725,19 +727,11 @@ public class CollectionUtils {
|
|||
* @param closure the closure to perform, may be null
|
||||
* @return the last element in the collection, or null if either iterator or closure is null
|
||||
* @since 4.0
|
||||
* @deprecated since 4.1, use {@link IteratorUtils#applyForAllButLast(Iterator, Closure)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static <T, C extends Closure<? super T>> T forAllButLastDo(final Iterator<T> iterator, final C closure) {
|
||||
if (iterator != null && closure != null) {
|
||||
while (iterator.hasNext()) {
|
||||
final T element = iterator.next();
|
||||
if (iterator.hasNext()) {
|
||||
closure.execute(element);
|
||||
} else {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return closure != null ? IteratorUtils.applyForAllButLast(iterator, closure) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -300,6 +300,16 @@ public class FluentIterable<E> implements Iterable<E> {
|
|||
return of(IterableUtils.uniqueIterable(iterable));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new FluentIterable whose iterator will return an unmodifiable
|
||||
* view of this iterable.
|
||||
*
|
||||
* @return a new iterable, providing an unmodifiable view of this iterable
|
||||
*/
|
||||
public FluentIterable<E> unmodifiable() {
|
||||
return of(IterableUtils.unmodifiableIterable(iterable));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new FluentIterable whose iterator will traverse
|
||||
* the elements of this iterable and the other iterable in
|
||||
|
|
|
@ -235,7 +235,7 @@ public class IterableUtils {
|
|||
* Returns a view of the given iterable that only contains elements matching
|
||||
* the provided predicate.
|
||||
* <p>
|
||||
* The returned iterable's iterator does not supports {@code remove()}.
|
||||
* The returned iterable's iterator does not support {@code remove()}.
|
||||
*
|
||||
* @param <E> the element type
|
||||
* @param iterable the iterable to filter, may be null
|
||||
|
@ -397,7 +397,7 @@ public class IterableUtils {
|
|||
* @param <I> the input element type
|
||||
* @param <O> the output element type
|
||||
* @param iterable the iterable to transform, may be null
|
||||
* @param transformer the transformer , must not be null
|
||||
* @param transformer the transformer, must not be null
|
||||
* @return a transformed view of the specified iterable
|
||||
* @throws NullPointerException if transformer is null
|
||||
*/
|
||||
|
@ -421,10 +421,10 @@ public class IterableUtils {
|
|||
/**
|
||||
* Returns a unique view of the given iterable.
|
||||
* <p>
|
||||
* The returned iterable's iterator does not supports {@code remove()}.
|
||||
* The returned iterable's iterator does not support {@code remove()}.
|
||||
*
|
||||
* @param <E> the element type
|
||||
* @param iterable the iterable to transform, may be null
|
||||
* @param iterable the iterable to use, may be null
|
||||
* @return a unique view of the specified iterable
|
||||
*/
|
||||
public static <E> Iterable<E> uniqueIterable(final Iterable<E> iterable) {
|
||||
|
@ -436,6 +436,44 @@ public class IterableUtils {
|
|||
};
|
||||
}
|
||||
|
||||
// Unmodifiable
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable view of the given iterable.
|
||||
* <p>
|
||||
* The returned iterable's iterator does not support {@code remove()}.
|
||||
*
|
||||
* @param <E> the element type
|
||||
* @param iterable the iterable to use, may be null
|
||||
* @return an unmodifiable view of the specified iterable
|
||||
*/
|
||||
public static <E> Iterable<E> unmodifiableIterable(final Iterable<E> iterable) {
|
||||
if (iterable instanceof UnmodifiableIterable<?>) {
|
||||
return iterable;
|
||||
}
|
||||
@SuppressWarnings("unchecked") // safe
|
||||
final Iterable<E> it = iterable != null ? iterable : EMPTY_ITERABLE;
|
||||
return new UnmodifiableIterable<E>(it);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner class to distinguish unmodifiable instances.
|
||||
*/
|
||||
private static final class UnmodifiableIterable<E> extends FluentIterable<E> {
|
||||
private final Iterable<E> unmodifiable;
|
||||
|
||||
public UnmodifiableIterable(final Iterable<E> iterable) {
|
||||
super();
|
||||
this.unmodifiable = iterable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return IteratorUtils.unmodifiableIterator(unmodifiable.iterator());
|
||||
}
|
||||
}
|
||||
|
||||
// Zipping
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
|
@ -515,6 +553,22 @@ public class IterableUtils {
|
|||
IteratorUtils.apply(emptyIteratorIfNull(iterable), closure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given closure on each but the last element in the iterable.
|
||||
* <p>
|
||||
* If the input iterable is null no change is made.
|
||||
*
|
||||
* @param <E> the type of object the {@link Iterable} contains
|
||||
* @param <C> the closure type
|
||||
* @param iterable the iterable to get the input from, may be null
|
||||
* @param closure the closure to perform, may not be null
|
||||
* @return the last element in the iterable, or null if iterable is null or empty
|
||||
*/
|
||||
public static <E, C extends Closure<? super E>> E applyForAllButLast(final Iterable<E> iterable,
|
||||
final C closure) {
|
||||
return IteratorUtils.applyForAllButLast(emptyIteratorIfNull(iterable), closure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the first element in the given iterable which matches the given predicate.
|
||||
* <p>
|
||||
|
|
|
@ -1251,6 +1251,37 @@ public class IteratorUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given closure on each but the last element in the iterator.
|
||||
* <p>
|
||||
* If the input iterator is null no change is made.
|
||||
*
|
||||
* @param <E> the type of object the {@link Iterator} contains
|
||||
* @param <C> the closure type
|
||||
* @param iterator the iterator to get the input from, may be null
|
||||
* @param closure the closure to perform, may not be null
|
||||
* @return the last element in the iterator, or null if iterator is null or empty
|
||||
* @throws NullPointerException if closure is null
|
||||
* @since 4.1
|
||||
*/
|
||||
public static <E, C extends Closure<? super E>> E applyForAllButLast(final Iterator<E> iterator,
|
||||
final C closure) {
|
||||
if (closure == null) {
|
||||
throw new NullPointerException("Closure must not be null.");
|
||||
}
|
||||
if (iterator != null) {
|
||||
while (iterator.hasNext()) {
|
||||
final E element = iterator.next();
|
||||
if (iterator.hasNext()) {
|
||||
closure.execute(element);
|
||||
} else {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the first element in the given iterator which matches the given predicate.
|
||||
* <p>
|
||||
|
|
|
@ -712,6 +712,7 @@ public class CollectionUtilsTest extends MockTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Deprecated
|
||||
public void forAllButLastDoIterator() {
|
||||
final Closure<List<? extends Number>> testClosure = ClosureUtils.invokerClosure("clear");
|
||||
final Collection<List<? extends Number>> col = new ArrayList<List<? extends Number>>();
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -282,6 +283,23 @@ public class FluentIterableTest {
|
|||
assertEquals(0, result.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unmodifiable() {
|
||||
FluentIterable<Integer> iterable1 = FluentIterable.of(iterableA).unmodifiable();
|
||||
Iterator<Integer> it = iterable1.iterator();
|
||||
assertEquals(1, it.next().intValue());
|
||||
try {
|
||||
it.remove();
|
||||
fail("expecting UnsupportedOperationException");
|
||||
} catch (UnsupportedOperationException ise) {
|
||||
// expected
|
||||
}
|
||||
|
||||
// calling unmodifiable on an already unmodifiable iterable shall return the same instance
|
||||
FluentIterable<Integer> iterable2 = iterable1.unmodifiable();
|
||||
assertSame(iterable1, iterable2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zip() {
|
||||
List<Integer> result = FluentIterable.of(iterableOdd).zip(iterableEven).toList();
|
||||
|
|
|
@ -133,6 +133,38 @@ public class IterableUtilsTest {
|
|||
IterableUtils.apply(col, testClosure);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applyForAllButLast() {
|
||||
final List<Integer> listA = new ArrayList<Integer>();
|
||||
listA.add(1);
|
||||
|
||||
final List<Integer> listB = new ArrayList<Integer>();
|
||||
listB.add(2);
|
||||
|
||||
final Closure<List<Integer>> testClosure = ClosureUtils.invokerClosure("clear");
|
||||
final Collection<List<Integer>> col = new ArrayList<List<Integer>>();
|
||||
col.add(listA);
|
||||
col.add(listB);
|
||||
List<Integer> last = IterableUtils.applyForAllButLast(col, testClosure);
|
||||
assertTrue(listA.isEmpty() && !listB.isEmpty());
|
||||
assertSame(listB, last);
|
||||
|
||||
try {
|
||||
IterableUtils.apply(col, null);
|
||||
fail("expecting NullPointerException");
|
||||
} catch (NullPointerException npe) {
|
||||
// expected
|
||||
}
|
||||
|
||||
IterableUtils.apply(null, testClosure);
|
||||
|
||||
// null should be OK
|
||||
col.add(null);
|
||||
col.add(null);
|
||||
last = IterableUtils.applyForAllButLast(col, testClosure);
|
||||
assertNull(last);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsWithEquator() {
|
||||
final List<String> base = new ArrayList<String>();
|
||||
|
|
|
@ -997,6 +997,38 @@ public class IteratorUtilsTest {
|
|||
IteratorUtils.apply(col.iterator(), testClosure);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applyForAllButLast() {
|
||||
final List<Integer> listA = new ArrayList<Integer>();
|
||||
listA.add(1);
|
||||
|
||||
final List<Integer> listB = new ArrayList<Integer>();
|
||||
listB.add(2);
|
||||
|
||||
final Closure<List<Integer>> testClosure = ClosureUtils.invokerClosure("clear");
|
||||
final Collection<List<Integer>> col = new ArrayList<List<Integer>>();
|
||||
col.add(listA);
|
||||
col.add(listB);
|
||||
List<Integer> last = IteratorUtils.applyForAllButLast(col.iterator(), testClosure);
|
||||
assertTrue(listA.isEmpty() && !listB.isEmpty());
|
||||
assertSame(listB, last);
|
||||
|
||||
try {
|
||||
IteratorUtils.apply(col.iterator(), null);
|
||||
fail("expecting NullPointerException");
|
||||
} catch (NullPointerException npe) {
|
||||
// expected
|
||||
}
|
||||
|
||||
IteratorUtils.apply(null, testClosure);
|
||||
|
||||
// null should be OK
|
||||
col.add(null);
|
||||
col.add(null);
|
||||
last = IteratorUtils.applyForAllButLast(col.iterator(), testClosure);
|
||||
assertNull(last);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void find() {
|
||||
Predicate<Number> testPredicate = equalPredicate((Number) 4);
|
||||
|
|
Loading…
Reference in New Issue