[LANG-1513] ObjectUtils: Get first non-null supplier value.

This commit is contained in:
Gary Gregory 2020-01-07 23:03:39 -05:00
parent 259ac721ce
commit a606a0328b
3 changed files with 63 additions and 0 deletions

View File

@ -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.">

View File

@ -209,6 +209,45 @@ public class ObjectUtils {
return null;
}
/**
* <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()}

View File

@ -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...)}.
*/