Add indexOf methods to IterableUtils and IteratorUtils, replace last occurrence of ArrayStack with ArrayDeque.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/trunk@1686921 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Thomas Neidhart 2015-06-22 19:48:47 +00:00
parent 68bbd2cf4a
commit 90509ce84e
5 changed files with 105 additions and 25 deletions

View File

@ -612,6 +612,22 @@ public class IterableUtils {
return IteratorUtils.find(emptyIteratorIfNull(iterable), predicate);
}
/**
* Returns the index of the first element in the specified iterable that
* matches the given predicate.
* <p>
* A <code>null</code> or empty iterable returns -1.
*
* @param <E> the element type
* @param iterable the iterable to search, may be null
* @param predicate the predicate to use, may not be null
* @return the index of the first element which matches the predicate or -1 if none matches
* @throws NullPointerException if predicate is null
*/
public static <E> int indexOf(final Iterable<E> iterable, final Predicate<? super E> predicate) {
return IteratorUtils.indexOf(emptyIteratorIfNull(iterable), predicate);
}
/**
* Answers true if a predicate is true for every element of an iterable.
* <p>

View File

@ -1281,6 +1281,35 @@ public class IteratorUtils {
return null;
}
/**
* Returns the index of the first element in the specified iterator that
* matches the given predicate.
* <p>
* A <code>null</code> or empty iterator returns -1.
*
* @param <E> the element type
* @param iterator the iterator to search, may be null
* @param predicate the predicate to use, may not be null
* @return the index of the first element which matches the predicate or -1 if none matches
* @throws NullPointerException if predicate is null
* @since 4.1
*/
public static <E> int indexOf(final Iterator<E> iterator, final Predicate<? super E> predicate) {
if (predicate == null) {
throw new NullPointerException("Predicate must not be null");
}
if (iterator != null) {
for(int index = 0; iterator.hasNext(); index++) {
final E element = iterator.next();
if (predicate.evaluate(element)) {
return index;
}
}
}
return -1;
}
/**
* Answers true if a predicate is true for any element of the iterator.
* <p>
@ -1294,19 +1323,7 @@ public class IteratorUtils {
* @since 4.1
*/
public static <E> boolean matchesAny(final Iterator<E> iterator, final Predicate<? super E> predicate) {
if (predicate == null) {
throw new NullPointerException("Predicate must not be null");
}
if (iterator != null) {
while (iterator.hasNext()) {
final E element = iterator.next();
if (predicate.evaluate(element)) {
return true;
}
}
}
return false;
return indexOf(iterator, predicate) != -1;
}
/**

View File

@ -19,8 +19,10 @@ package org.apache.commons.collections4;
import java.io.PrintStream;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
@ -918,7 +920,7 @@ public class MapUtils {
* @throws NullPointerException if the stream is <code>null</code>
*/
public static void verbosePrint(final PrintStream out, final Object label, final Map<?, ?> map) {
verbosePrintInternal(out, label, map, new ArrayStack<Map<?, ?>>(), false);
verbosePrintInternal(out, label, map, new ArrayDeque<Map<?, ?>>(), false);
}
/**
@ -940,7 +942,7 @@ public class MapUtils {
* @throws NullPointerException if the stream is <code>null</code>
*/
public static void debugPrint(final PrintStream out, final Object label, final Map<?, ?> map) {
verbosePrintInternal(out, label, map, new ArrayStack<Map<?, ?>>(), true);
verbosePrintInternal(out, label, map, new ArrayDeque<Map<?, ?>>(), true);
}
// Implementation methods
@ -969,7 +971,7 @@ public class MapUtils {
* @throws NullPointerException if the stream is <code>null</code>
*/
private static void verbosePrintInternal(final PrintStream out, final Object label, final Map<?, ?> map,
final ArrayStack<Map<?, ?>> lineage, final boolean debug) {
final Deque<Map<?, ?>> lineage, final boolean debug) {
printIndent(out, lineage.size());
if (map == null) {
@ -988,7 +990,7 @@ public class MapUtils {
printIndent(out, lineage.size());
out.println("{");
lineage.push(map);
lineage.addLast(map);
for (final Map.Entry<?, ?> entry : map.entrySet()) {
final Object childKey = entry.getKey();
@ -1005,7 +1007,9 @@ public class MapUtils {
out.print(childKey);
out.print(" = ");
final int lineageIndex = lineage.indexOf(childValue);
final int lineageIndex =
IterableUtils.indexOf(lineage,
PredicateUtils.equalPredicate(childValue));
if (lineageIndex == -1) {
out.print(childValue);
} else if (lineage.size() - 1 == lineageIndex) {
@ -1026,7 +1030,7 @@ public class MapUtils {
}
}
lineage.pop();
lineage.removeLast();
printIndent(out, lineage.size());
out.println(debug ? "} " + map.getClass().getName() : "}");

View File

@ -292,6 +292,23 @@ public class IterableUtilsTest {
}
}
@Test
public void indexOf() {
Predicate<Number> testPredicate = equalPredicate((Number) 4);
int index = IterableUtils.indexOf(iterableA, testPredicate);
assertEquals(6, index);
testPredicate = equalPredicate((Number) 45);
index = IterableUtils.indexOf(iterableA, testPredicate);
assertEquals(-1, index);
assertEquals(-1, IterableUtils.indexOf(null, testPredicate));
try {
assertNull(IterableUtils.indexOf(iterableA, null));
fail("expecting NullPointerException");
} catch (final NullPointerException npe) {
// expected
}
}
@Test
public void countMatches() {
assertEquals(4, IterableUtils.countMatches(iterableB, EQUALS_TWO));

View File

@ -16,9 +16,16 @@
*/
package org.apache.commons.collections4;
import static org.apache.commons.collections4.functors.EqualPredicate.*;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;
import static org.apache.commons.collections4.functors.EqualPredicate.equalPredicate;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Arrays;
@ -64,7 +71,7 @@ public class IteratorUtilsTest {
private Iterable<Integer> iterableA = null;
private Collection<Integer> emptyCollection = new ArrayList<Integer>(1);
private final Collection<Integer> emptyCollection = new ArrayList<Integer>(1);
@Before
public void setUp() {
@ -908,9 +915,11 @@ public class IteratorUtilsTest {
*/
private NodeList createNodeList(final Node[] nodes) {
return new NodeList() {
@Override
public Node item(final int index) {
return nodes[index];
}
@Override
public int getLength() {
return nodes.length;
}
@ -957,8 +966,8 @@ public class IteratorUtilsTest {
final Comparator<Integer> reverseComparator =
ComparatorUtils.reversedComparator(ComparatorUtils.<Integer>naturalComparator());
Collections.reverse((List<Integer>) collectionOdd);
Collections.reverse((List<Integer>) collectionEven);
Collections.reverse(collectionOdd);
Collections.reverse(collectionEven);
Collections.reverse(combinedList);
it = IteratorUtils.collatedIterator(reverseComparator,
@ -1046,6 +1055,23 @@ public class IteratorUtilsTest {
}
}
@Test
public void indexOf() {
Predicate<Number> testPredicate = equalPredicate((Number) 4);
int index = IteratorUtils.indexOf(iterableA.iterator(), testPredicate);
assertEquals(6, index);
testPredicate = equalPredicate((Number) 45);
index = IteratorUtils.indexOf(iterableA.iterator(), testPredicate);
assertEquals(-1, index);
assertEquals(-1, IteratorUtils.indexOf(null, testPredicate));
try {
assertNull(IteratorUtils.indexOf(iterableA.iterator(), null));
fail("expecting NullPointerException");
} catch (final NullPointerException npe) {
// expected
}
}
@Test
public void getFromIterator() throws Exception {
// Iterator, entry exists