[COLLECTIONS-450] Added CollectionUtils.forAllButLastDo(...) methods. Thanks to J. Moldawski
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/trunk@1475937 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f7c4d60cda
commit
cb3b31ed23
|
@ -28,6 +28,10 @@
|
|||
<action issue="COLLECTIONS-451" dev="tn" type="update">
|
||||
The constructors for all Utils classes are now private to prevent instantiation.
|
||||
</action>
|
||||
<action issue="COLLECTIONS-450" dev="tn" type="add" due-to="J. Moldawski">
|
||||
Added methods "forAllButLastDo(Collection, Closure)" and "forAllButLastDo(Iterator, Closure)"
|
||||
to class "CollectionUtils".
|
||||
</action>
|
||||
<action issue="COLLECTIONS-447" dev="tn" type="fix" due-to="Jeffrey Barnes">
|
||||
Tree traversal with a TreeListIterator will not be affected anymore by
|
||||
the removal of an element directly after a call to previous().
|
||||
|
|
|
@ -694,6 +694,47 @@ public class CollectionUtils {
|
|||
return closure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given closure on each but the last element in the collection.
|
||||
* <p>
|
||||
* If the input collection or closure is null, there is no change made.
|
||||
*
|
||||
* @param <T> the type of object the {@link Collection} contains
|
||||
* @param <C> the closure type
|
||||
* @param collection the collection to get the input from, may be null
|
||||
* @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
|
||||
*/
|
||||
public static <T, C extends Closure<? super T>> T forAllButLastDo(final Collection<T> collection,
|
||||
final C closure) {
|
||||
return collection != null && closure != null ? forAllButLastDo(collection.iterator(), closure) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given closure on each but the last element in the collection.
|
||||
* <p>
|
||||
* If the input collection or closure is null, there is no change made.
|
||||
*
|
||||
* @param <T> the type of object the {@link Collection} 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 be null
|
||||
* @return the last element in the collection, or null if either iterator or closure is null
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the collection by applying a Predicate to each element. If the
|
||||
* predicate returns false, remove the element.
|
||||
|
|
|
@ -663,6 +663,61 @@ public class CollectionUtilsTest extends MockTestCase {
|
|||
CollectionUtils.forAllDo(col, testClosure);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forAllButLastDoCollection() {
|
||||
final Closure<List<? extends Number>> testClosure = ClosureUtils.invokerClosure("clear");
|
||||
final Collection<List<? extends Number>> col = new ArrayList<List<? extends Number>>();
|
||||
col.add(collectionA);
|
||||
col.add(collectionB);
|
||||
List<? extends Number> lastElement = CollectionUtils.forAllButLastDo(col, testClosure);
|
||||
assertSame(lastElement, collectionB);
|
||||
assertTrue(collectionA.isEmpty() && !collectionB.isEmpty());
|
||||
|
||||
col.clear();
|
||||
col.add(collectionB);
|
||||
lastElement = CollectionUtils.forAllButLastDo(col, testClosure);
|
||||
assertSame(lastElement, collectionB);
|
||||
assertTrue(!collectionB.isEmpty() );
|
||||
|
||||
col.clear();
|
||||
lastElement = CollectionUtils.forAllButLastDo(col, testClosure);
|
||||
assertNull(lastElement);
|
||||
|
||||
Collection<String> strings = Arrays.asList(new String[]{"a", "b", "c"});
|
||||
final StringBuffer result = new StringBuffer();
|
||||
result.append(CollectionUtils.forAllButLastDo(strings, new Closure<String>() {
|
||||
public void execute(String input) {
|
||||
result.append(input+";");
|
||||
}
|
||||
}));
|
||||
assertEquals("a;b;c", result.toString());
|
||||
|
||||
Collection<String> oneString = Arrays.asList(new String[]{"a"});
|
||||
final StringBuffer resultOne = new StringBuffer();
|
||||
resultOne.append(CollectionUtils.forAllButLastDo(oneString, new Closure<String>() {
|
||||
public void execute(String input) {
|
||||
resultOne.append(input+";");
|
||||
}
|
||||
}));
|
||||
assertEquals("a", resultOne.toString());
|
||||
assertNull(CollectionUtils.forAllButLastDo(strings, null));
|
||||
assertNull(CollectionUtils.forAllButLastDo((Collection<?>) null, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forAllButLastDoIterator() {
|
||||
final Closure<List<? extends Number>> testClosure = ClosureUtils.invokerClosure("clear");
|
||||
final Collection<List<? extends Number>> col = new ArrayList<List<? extends Number>>();
|
||||
col.add(collectionA);
|
||||
col.add(collectionB);
|
||||
List<? extends Number> lastElement = CollectionUtils.forAllButLastDo(col.iterator(), testClosure);
|
||||
assertSame(lastElement, collectionB);
|
||||
assertTrue(collectionA.isEmpty() && !collectionB.isEmpty());
|
||||
|
||||
assertNull(CollectionUtils.forAllButLastDo(col.iterator(), null));
|
||||
assertNull(CollectionUtils.forAllButLastDo((Collection<?>) null, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFromMap() {
|
||||
// Unordered map, entries exist
|
||||
|
|
Loading…
Reference in New Issue