From 90509ce84e7d1c9f78ea0aa919ac373159fb28ae Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Mon, 22 Jun 2015 19:48:47 +0000 Subject: [PATCH] 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 --- .../commons/collections4/IterableUtils.java | 16 +++++++ .../commons/collections4/IteratorUtils.java | 43 +++++++++++++------ .../apache/commons/collections4/MapUtils.java | 16 ++++--- .../collections4/IterableUtilsTest.java | 17 ++++++++ .../collections4/IteratorUtilsTest.java | 38 +++++++++++++--- 5 files changed, 105 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/apache/commons/collections4/IterableUtils.java b/src/main/java/org/apache/commons/collections4/IterableUtils.java index 540d60457..6e1001032 100644 --- a/src/main/java/org/apache/commons/collections4/IterableUtils.java +++ b/src/main/java/org/apache/commons/collections4/IterableUtils.java @@ -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. + *

+ * A null or empty iterable returns -1. + * + * @param 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 int indexOf(final Iterable iterable, final Predicate predicate) { + return IteratorUtils.indexOf(emptyIteratorIfNull(iterable), predicate); + } + /** * Answers true if a predicate is true for every element of an iterable. *

diff --git a/src/main/java/org/apache/commons/collections4/IteratorUtils.java b/src/main/java/org/apache/commons/collections4/IteratorUtils.java index b8e8c4c1a..d7090a37a 100644 --- a/src/main/java/org/apache/commons/collections4/IteratorUtils.java +++ b/src/main/java/org/apache/commons/collections4/IteratorUtils.java @@ -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. + *

+ * A null or empty iterator returns -1. + * + * @param 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 int indexOf(final Iterator iterator, final Predicate 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. *

@@ -1294,19 +1323,7 @@ public class IteratorUtils { * @since 4.1 */ public static boolean matchesAny(final Iterator iterator, final Predicate 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; } /** diff --git a/src/main/java/org/apache/commons/collections4/MapUtils.java b/src/main/java/org/apache/commons/collections4/MapUtils.java index b6786bbcb..39f33389b 100644 --- a/src/main/java/org/apache/commons/collections4/MapUtils.java +++ b/src/main/java/org/apache/commons/collections4/MapUtils.java @@ -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 null */ public static void verbosePrint(final PrintStream out, final Object label, final Map map) { - verbosePrintInternal(out, label, map, new ArrayStack>(), false); + verbosePrintInternal(out, label, map, new ArrayDeque>(), false); } /** @@ -940,7 +942,7 @@ public class MapUtils { * @throws NullPointerException if the stream is null */ public static void debugPrint(final PrintStream out, final Object label, final Map map) { - verbosePrintInternal(out, label, map, new ArrayStack>(), true); + verbosePrintInternal(out, label, map, new ArrayDeque>(), true); } // Implementation methods @@ -969,7 +971,7 @@ public class MapUtils { * @throws NullPointerException if the stream is null */ private static void verbosePrintInternal(final PrintStream out, final Object label, final Map map, - final ArrayStack> lineage, final boolean debug) { + final Deque> 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() : "}"); diff --git a/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java b/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java index ac852abcf..769b34b73 100644 --- a/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java @@ -292,6 +292,23 @@ public class IterableUtilsTest { } } + @Test + public void indexOf() { + Predicate 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)); diff --git a/src/test/java/org/apache/commons/collections4/IteratorUtilsTest.java b/src/test/java/org/apache/commons/collections4/IteratorUtilsTest.java index 0fc3063e5..e9b5105f4 100644 --- a/src/test/java/org/apache/commons/collections4/IteratorUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/IteratorUtilsTest.java @@ -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 iterableA = null; - private Collection emptyCollection = new ArrayList(1); + private final Collection emptyCollection = new ArrayList(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 reverseComparator = ComparatorUtils.reversedComparator(ComparatorUtils.naturalComparator()); - Collections.reverse((List) collectionOdd); - Collections.reverse((List) 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 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