This is an automated email from the ASF dual-hosted git repository.
daim pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
The following commit(s) were added to refs/heads/trunk by this push:
new a2595d9cb9 OAK-11575 : added util to replace Iterables.getLast in
oak-commons (#2162)
a2595d9cb9 is described below
commit a2595d9cb99fceb1643b4c6214ffef91cc176a96
Author: Rishabh Kumar <[email protected]>
AuthorDate: Tue Mar 11 13:21:43 2025 +0530
OAK-11575 : added util to replace Iterables.getLast in oak-commons (#2162)
* OAK-11575 : added util to replace Iterables.getLast in oak-commons
* OAK-11575 : addressed review comments to update comments
---------
Co-authored-by: Rishabh Kumar <[email protected]>
---
.../oak/commons/collections/IterableUtils.java | 28 +++++++++
.../oak/commons/collections/IterableUtilsTest.java | 72 ++++++++++++++++++++++
2 files changed, 100 insertions(+)
diff --git
a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/collections/IterableUtils.java
b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/collections/IterableUtils.java
index a09e096e60..9f7b8d393a 100644
---
a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/collections/IterableUtils.java
+++
b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/collections/IterableUtils.java
@@ -446,4 +446,32 @@ public class IterableUtils {
Objects.requireNonNull(predicate, "Predicate must not be null.");
return org.apache.commons.collections4.IterableUtils.find(iterable,
predicate::test);
}
+
+ /**
+ * Returns the last element of the specified iterable, or null if the
iterable is empty.
+ * <p>
+ * The iterable must be fully traversed to find the last element.
+ *
+ * @param <T> the type of elements in the iterable
+ * @param iterable the iterable to get the last element from, must not be
null
+ * @return the last element in the iterable or null if the iterable is
empty
+ */
+ public static <T> T getLast(final Iterable<T> iterable) {
+
+ Objects.requireNonNull(iterable, "Iterable must not be null.");
+
+ // Optimize for Lists
+ if (iterable instanceof List) {
+ final List<T> list = (List<T>) iterable;
+ return list.isEmpty() ? null : list.get(list.size() - 1);
+ }
+
+ // For non-List iterables
+ T last = null;
+ for (final T element : iterable) {
+ last = element;
+ }
+
+ return last;
+ }
}
diff --git
a/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/collections/IterableUtilsTest.java
b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/collections/IterableUtilsTest.java
index 7984918191..4acd80283c 100644
---
a/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/collections/IterableUtilsTest.java
+++
b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/collections/IterableUtilsTest.java
@@ -26,9 +26,11 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
+import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -1030,4 +1032,74 @@ public class IterableUtilsTest {
Integer result = IterableUtils.find(customIterable, i -> i % 10 == 0);
Assert.assertEquals(Integer.valueOf(10), result);
}
+
+ @Test
+ public void testGetLastWithNonEmptyIterable() {
+ List<String> list = Arrays.asList("a", "b", "c");
+ String result = IterableUtils.getLast(list);
+ Assert.assertEquals("c", result);
+ }
+
+ @Test
+ public void testGetLastWithEmptyIterable() {
+ List<String> list = Collections.emptyList();
+ String result = IterableUtils.getLast(list);
+ Assert.assertNull(result);
+ }
+
+ @Test
+ public void testGetLastWithNullIterable() {
+ Assert.assertThrows(NullPointerException.class, () ->
IterableUtils.getLast(null));
+ }
+
+ @Test
+ public void testGetLastWithSingleElement() {
+ List<Integer> list = Collections.singletonList(42);
+ Integer result = IterableUtils.getLast(list);
+ Assert.assertEquals(Integer.valueOf(42), result);
+ }
+
+ @Test
+ public void testGetLastWithNullLastElement() {
+ List<String> list = Arrays.asList("a", "b", null);
+ String result = IterableUtils.getLast(list);
+ Assert.assertNull(result);
+ }
+
+ @Test
+ public void testGetLastWithCustomIterable() {
+ // Custom iterable that doesn't implement Collection
+ Iterable<Integer> customIterable = () -> Arrays.asList(5, 10,
15).iterator();
+ Integer result = IterableUtils.getLast(customIterable);
+ Assert.assertEquals(Integer.valueOf(15), result);
+ }
+
+ @Test
+ public void testGetLastWithLargeIterable() {
+ List<Integer> list = new ArrayList<>();
+ for (int i = 0; i < 1000; i++) {
+ list.add(i);
+ }
+ Integer result = IterableUtils.getLast(list);
+ Assert.assertEquals(Integer.valueOf(999), result);
+ }
+
+ @Test
+ public void testGetLastWithListImplementation() {
+ // Test to confirm optimization for List works
+ List<String> list = Arrays.asList("a", "b", "c", "d");
+ String result = IterableUtils.getLast(list);
+ Assert.assertEquals("d", result);
+ }
+
+ @Test
+ public void testGetLastWithNonListCollection() {
+ // Test with a Collection that isn't a List
+ Set<String> set = new LinkedHashSet<>();
+ set.add("a");
+ set.add("b");
+ set.add("c");
+ String result = IterableUtils.getLast(set);
+ Assert.assertEquals("c", result);
+ }
}