Skip to content

Commit 2b7c79c

Browse files
author
Vincent Potucek
committedMar 14, 2025
move
1 parent c015d1c commit 2b7c79c

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed
 

‎src/main/java/org/apache/commons/lang3/ObjectUtils.java

+29
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,35 @@ public static <T> T firstNonNull(final T... values) {
640640
return Streams.of(values).filter(Objects::nonNull).findFirst().orElse(null);
641641
}
642642

643+
/**
644+
* Returns the first value in the collection which is not {@code null}.
645+
* If all the values are {@code null} or the collection is {@code null}
646+
* or empty then {@code null} is returned.
647+
*
648+
* <pre>
649+
* ObjectUtils.firstNonNull(null, null) = null
650+
* ObjectUtils.firstNonNull(null, "") = ""
651+
* ObjectUtils.firstNonNull(null, null, "") = ""
652+
* ObjectUtils.firstNonNull(null, "zz") = "zz"
653+
* ObjectUtils.firstNonNull("abc", *) = "abc"
654+
* ObjectUtils.firstNonNull(null, "xyz", *) = "xyz"
655+
* ObjectUtils.firstNonNull(Boolean.TRUE, *) = Boolean.TRUE
656+
* ObjectUtils.firstNonNull() = null
657+
* </pre>
658+
*
659+
* @param <T> the component type of the collection
660+
* @param values the collection to test, may be {@code null} or empty
661+
* @return the first value from {@code values} which is not {@code null},
662+
* or {@code null} if there are no non-null values
663+
* @since 3.0
664+
*/
665+
public static <T> Optional<T> firstNonNull(final Collection<T> values) {
666+
if (Objects.isNull(values) || values.isEmpty()) {
667+
return Optional.empty();
668+
}
669+
return values.stream().filter(Objects::nonNull).findFirst();
670+
}
671+
643672
/**
644673
* Delegates to {@link Object#getClass()} using generics.
645674
*

‎src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java

+15-1
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ public void testEquals() {
478478
}
479479

480480
@Test
481-
public void testFirstNonNull() {
481+
public void testFirstNonNullArray() {
482482
assertEquals("", ObjectUtils.firstNonNull(null, ""));
483483
final String firstNonNullGenerics = ObjectUtils.firstNonNull(null, null, "123", "456");
484484
assertEquals("123", firstNonNullGenerics);
@@ -495,6 +495,20 @@ public void testFirstNonNull() {
495495
assertNull(ObjectUtils.firstNonNull((Object[]) null));
496496
}
497497

498+
@Test
499+
void testFirstNonNullCollection() {
500+
assertEquals("", ObjectUtils.firstNonNull(Collections.singletonList("")));
501+
assertEquals("123", ObjectUtils.firstNonNull(Arrays.asList(null, null, "123", "456")));
502+
assertEquals("123", ObjectUtils.firstNonNull(Arrays.asList("123", null, "456", null)));
503+
assertSame(Boolean.TRUE, ObjectUtils.firstNonNull(Collections.singletonList(Boolean.TRUE)));
504+
505+
// Ensure an empty collection returns null
506+
assertNull(ObjectUtils.firstNonNull(Collections.emptyList()));
507+
508+
// Ensure collection with only nulls returns null
509+
assertNull(ObjectUtils.firstNonNull(Arrays.asList(null, null)));
510+
}
511+
498512
@Test
499513
public void testGetClass() {
500514
final String[] newArray = ArrayUtils.EMPTY_STRING_ARRAY;

0 commit comments

Comments
 (0)