You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2020/01/08 04:03:46 UTC

[commons-lang] branch master updated: [LANG-1513] ObjectUtils: Get first non-null supplier value.

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git


The following commit(s) were added to refs/heads/master by this push:
     new a606a03  [LANG-1513] ObjectUtils: Get first non-null supplier value.
a606a03 is described below

commit a606a0328ba4b3061c5bc810a31418fa4251ea16
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Tue Jan 7 23:03:39 2020 -0500

    [LANG-1513] ObjectUtils: Get first non-null supplier value.
---
 src/changes/changes.xml                            |  1 +
 .../java/org/apache/commons/lang3/ObjectUtils.java | 39 ++++++++++++++++++++++
 .../org/apache/commons/lang3/ObjectUtilsTest.java  | 23 +++++++++++++
 3 files changed, 63 insertions(+)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 2a307cb..11f89c4 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -94,6 +94,7 @@ The <action> type attribute can be add,update,fix,remove.
     <action issue="LANG-1509" type="add" dev="ggregory" due-to="Gary Gregory">Add ObjectToStringComparator. #483.</action>
     <action issue="LANG-1510" type="add" dev="ggregory" due-to="Gary Gregory">Add org.apache.commons.lang3.arch.Processor.Arch.getLabel().</action>
     <action issue="LANG-1512" type="add" dev="ggregory" due-to="Gary Gregory">Add IS_JAVA_14 and IS_JAVA_15 to org.apache.commons.lang3.SystemUtils.</action>
+    <action issue="LANG-1513" type="add" dev="ggregory" due-to="Bernhard Bonigl, Gary Gregory">ObjectUtils: Get first non-null supplier value.</action>
   </release>
 
   <release version="3.9" date="2019-04-09" description="New features and bug fixes. Requires Java 8, supports Java 9, 10, 11.">
diff --git a/src/main/java/org/apache/commons/lang3/ObjectUtils.java b/src/main/java/org/apache/commons/lang3/ObjectUtils.java
index 3b83ce1..b647c1a 100644
--- a/src/main/java/org/apache/commons/lang3/ObjectUtils.java
+++ b/src/main/java/org/apache/commons/lang3/ObjectUtils.java
@@ -210,6 +210,45 @@ public class ObjectUtils {
     }
 
     /**
+     * <p>Executes the given suppliers in order and returns the first return
+     * value where a value other than {@code null} is returned.
+     * Once a non-{@code null} value is obtained, all following suppliers are
+     * not executed anymore.
+     * If all the return values are {@code null} or no suppliers are provided
+     * then {@code null} is returned.</p>
+     *
+     * <pre>
+     * ObjectUtils.firstNonNullLazy(null, () -&gt; null) = null
+     * ObjectUtils.firstNonNullLazy(() -&gt; null, () -&gt; "") = ""
+     * ObjectUtils.firstNonNullLazy(() -&gt; "", () -&gt; throw new IllegalStateException()) = ""
+     * ObjectUtils.firstNonNullLazy(() -&gt; null, () -&gt; "zz) = "zz"
+     * ObjectUtils.firstNonNullLazy() = null
+     * </pre>
+     *
+     * @param <T> the type of the return values
+     * @param suppliers  the suppliers returning the values to test.
+     *                   {@code null} values are ignored.
+     *                   Suppliers may return {@code null} or a value of type @{code T}
+     * @return the first return value from {@code suppliers} which is not {@code null},
+     *  or {@code null} if there are no non-null values
+     * @since 3.10
+     */
+    @SafeVarargs
+    public static <T> T getFirstNonNull(final Supplier<T>... suppliers) {
+        if (suppliers != null) {
+            for (final Supplier<T> supplier : suppliers) {
+                if (supplier != null) {
+                    T value = supplier.get();
+                    if (value != null) {
+                        return value;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
      * <p>
      * Returns the given {@code object} is it is non-null, otherwise returns the Supplier's {@link Supplier#get()}
      * value.
diff --git a/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java b/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java
index 19d6110..7fcdc4b 100644
--- a/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java
@@ -25,6 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertSame;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.lang.reflect.Constructor;
@@ -149,6 +150,28 @@ public class ObjectUtilsTest {
         assertNull(ObjectUtils.firstNonNull((Object[]) null));
     }
 
+    @Test
+    public void testGetFirstNonNull() {
+        // first non null
+        assertEquals("", ObjectUtils.getFirstNonNull(() -> null, () -> ""));
+        // first encountered value is used
+        assertEquals("1", ObjectUtils.getFirstNonNull(() -> null, () -> "1", () -> "2", () -> null));
+        assertEquals("123", ObjectUtils.getFirstNonNull(() -> "123", () -> null, () -> "456"));
+        // don't evaluate suppliers after first value is found
+        assertEquals("123", ObjectUtils.getFirstNonNull(() -> null, () -> "123", () -> fail("Supplier after first non-null value should not be evaluated")));
+        // supplier returning null and null supplier both result in null
+        assertNull(ObjectUtils.getFirstNonNull(null, () -> null));
+        // Explicitly pass in an empty array of Object type to ensure compiler doesn't complain of unchecked generic array creation
+        assertNull(ObjectUtils.getFirstNonNull());
+        // supplier is null
+        assertNull(ObjectUtils.getFirstNonNull((Supplier<Object>) null));
+        // varargs array itself is null
+        assertNull(ObjectUtils.getFirstNonNull((Supplier<Object>[]) null));
+        // test different types
+        assertEquals(1, ObjectUtils.getFirstNonNull(() -> null, () -> 1));
+        assertEquals(Boolean.TRUE, ObjectUtils.getFirstNonNull(() -> null, () -> Boolean.TRUE));
+    }
+
     /**
      * Tests {@link ObjectUtils#anyNotNull(Object...)}.
      */