You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by da...@apache.org on 2025/05/08 08:47:39 UTC
(jackrabbit-oak) 01/01: OAK-11706 : added Iterators.limit replacement in oak-commons
This is an automated email from the ASF dual-hosted git repository.
daim pushed a commit to branch OAK-11706
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
commit a59915a051c89ab10d6fa2b30d277cc15f19ffc6
Author: Rishabh Kumar <di...@adobe.com>
AuthorDate: Thu May 8 14:17:24 2025 +0530
OAK-11706 : added Iterators.limit replacement in oak-commons
---
.../oak/commons/collections/IteratorUtils.java | 27 +++++++
.../oak/commons/collections/IteratorUtilsTest.java | 91 ++++++++++++++++++++++
2 files changed, 118 insertions(+)
diff --git a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/collections/IteratorUtils.java b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/collections/IteratorUtils.java
index 7d98918b8c..5c01691d71 100644
--- a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/collections/IteratorUtils.java
+++ b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/collections/IteratorUtils.java
@@ -531,5 +531,32 @@ public class IteratorUtils {
}
});
}
+
+ /**
+ * Returns an iterator that will only provide at most the first N elements from given iterator.
+ * <p>
+ * This method returns an iterator that will stop after returning the
+ * specified number of elements or when the source iterator is exhausted,
+ * whichever comes first.
+ * <p>
+ * Example usage:
+ * <pre>
+ * Iterator<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David").iterator();
+ * Iterator<String> firstTwo = IteratorUtils.limit(names, 2);
+ * // firstTwo will iterate through "Alice", "Bob" only
+ * </pre>
+ *
+ * @param <T> the type of elements in the iterator
+ * @param iterator the source iterator to limit, must not be null
+ * @param limit the maximum number of elements to return, must not be negative
+ * @return an iterator limited to the specified number of elements
+ * @throws NullPointerException if the iterator is null
+ * @throws IllegalArgumentException if limit is negative
+ */
+ public static <T> Iterator<T> limit(final Iterator<T> iterator, final int limit) {
+ Objects.requireNonNull(iterator);
+ Validate.checkArgument(limit >= 0, "limit is negative");
+ return org.apache.commons.collections4.IteratorUtils.boundedIterator(iterator, limit);
+ }
}
diff --git a/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/collections/IteratorUtilsTest.java b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/collections/IteratorUtilsTest.java
index 7abc2a8186..d2db77d784 100644
--- a/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/collections/IteratorUtilsTest.java
+++ b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/collections/IteratorUtilsTest.java
@@ -1246,4 +1246,95 @@ public class IteratorUtilsTest {
// But original list should still have all elements
Assert.assertEquals(Arrays.asList("a", "b", "c", "d"), list);
}
+
+ @Test
+ public void testLimitWithSmallerLimit() {
+ List<String> list = Arrays.asList("a", "b", "c", "d");
+ Iterator<String> limited = IteratorUtils.limit(list.iterator(), 2);
+
+ Assert.assertTrue(limited.hasNext());
+ Assert.assertEquals("a", limited.next());
+ Assert.assertTrue(limited.hasNext());
+ Assert.assertEquals("b", limited.next());
+ Assert.assertFalse(limited.hasNext());
+ }
+
+ @Test
+ public void testLimitWithLargerLimit() {
+ List<String> list = Arrays.asList("a", "b", "c");
+ Iterator<String> limited = IteratorUtils.limit(list.iterator(), 5);
+
+ Assert.assertTrue(limited.hasNext());
+ Assert.assertEquals("a", limited.next());
+ Assert.assertTrue(limited.hasNext());
+ Assert.assertEquals("b", limited.next());
+ Assert.assertTrue(limited.hasNext());
+ Assert.assertEquals("c", limited.next());
+ Assert.assertFalse(limited.hasNext());
+ }
+
+ @Test
+ public void testLimitWithEqualLimit() {
+ List<String> list = Arrays.asList("a", "b", "c");
+ Iterator<String> limited = IteratorUtils.limit(list.iterator(), 3);
+
+ Assert.assertTrue(limited.hasNext());
+ Assert.assertEquals("a", limited.next());
+ Assert.assertTrue(limited.hasNext());
+ Assert.assertEquals("b", limited.next());
+ Assert.assertTrue(limited.hasNext());
+ Assert.assertEquals("c", limited.next());
+ Assert.assertFalse(limited.hasNext());
+ }
+
+ @Test
+ public void testLimitWithZeroLimit() {
+ List<String> list = Arrays.asList("a", "b", "c");
+ Iterator<String> limited = IteratorUtils.limit(list.iterator(), 0);
+
+ Assert.assertFalse(limited.hasNext());
+ }
+
+ @Test
+ public void testLimitWithEmptyIterator() {
+ Iterator<String> limited = IteratorUtils.limit(Collections.emptyIterator(), 5);
+ Assert.assertFalse(limited.hasNext());
+ }
+
+ @Test
+ public void testLimitWithNullIterator() {
+ Assert.assertThrows(NullPointerException.class, () -> IteratorUtils.limit(null, 5));
+ }
+
+ @Test
+ public void testLimitWithNegativeLimit() {
+ final List<String> list = List.of("a", "b", "c");
+ Assert.assertThrows(IllegalArgumentException.class, () -> IteratorUtils.limit(list.iterator(), -1));
+ }
+
+ @Test
+ public void testLimitWithRemove() {
+ List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
+ Iterator<String> limited = IteratorUtils.limit(list.iterator(), 2);
+
+ Assert.assertEquals("a", limited.next());
+ limited.remove(); // Remove "a"
+ Assert.assertEquals("b", limited.next());
+
+ Assert.assertEquals(List.of("b", "c"), list);
+ }
+
+ @Test
+ public void testLimitChaining() {
+ List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
+ Iterator<Integer> limited = IteratorUtils.limit(list.iterator(), 4); // First 4 elements
+ Iterator<Integer> furtherLimited = IteratorUtils.limit(limited, 2); // First 2 of those 4
+
+ List<Integer> result = new ArrayList<>();
+ while (furtherLimited.hasNext()) {
+ result.add(furtherLimited.next());
+ }
+
+ Assert.assertEquals(List.of(1, 2), result);
+ }
}