From 11c1c8eeef8b1619dac4f006f8927bed9d10ff74 Mon Sep 17 00:00:00 2001 From: Vincent Potucek Date: Thu, 13 Mar 2025 10:26:57 +0100 Subject: [PATCH 1/4] add ObjectUtils.defaultIfNull Signed-off-by: Vincent Potucek --- .../org/springframework/util/ObjectUtils.java | 42 +++++++++++++++++++ .../util/ObjectUtilsTests.java | 32 ++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java index 34a2be4e3099..55943bae7fa9 100644 --- a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java @@ -118,6 +118,48 @@ public static boolean isEmpty(@Nullable Object @Nullable [] array) { return (array == null || array.length == 0); } + /** + * Returns the object if it is not {@code null}; otherwise, returns the default value. + * + *
+	 * ObjectUtils.getIfNull(null, null)      = null
+	 * ObjectUtils.getIfNull(null, "")        = ""
+	 * ObjectUtils.getIfNull(null, "zz")      = "zz"
+	 * ObjectUtils.getIfNull("abc", *)        = "abc"
+	 * ObjectUtils.getIfNull(Boolean.TRUE, *) = Boolean.TRUE
+	 * 
+ * + * @param the type of the object + * @param object the object to test, may be {@code null} + * @param defaultValue the default value to return if the object is {@code null}, may be {@code null} + * @return {@code object} if it is not {@code null}; otherwise, {@code defaultValue} + */ + @Nullable + public static T getIfNull(@Nullable final T object, @Nullable final T defaultValue) { + return Objects.nonNull(object) ? object : defaultValue; + } + + /** + * Returns the collection if it is not {@code null} and not empty; otherwise, returns the default value. + * + *
+	 * ObjectUtils.getIfEmpty(List.of("a"), List.of("b"))     			= List.of("a")
+	 * ObjectUtils.getIfEmpty(null, List.of("b"))            			= List.of("b")
+	 * ObjectUtils.getIfEmpty(Collections.emptyList(), List.of("b")) 	= List.of("b")
+	 * ObjectUtils.getIfEmpty(null, null)                    			= null
+	 * 
+ * + * @param the type of elements in the collection + * @param object the collection to test, may be {@code null} + * @param defaultValue the default value to return if the collection is {@code null} or empty, may be {@code null} + * @return {@code object} if it is not {@code null} and not empty; otherwise, {@code defaultValue} + */ + @Nullable + public static Collection getIfEmpty(@Nullable final Collection object, + @Nullable final Collection defaultValue) { + return Objects.nonNull(object) && !object.isEmpty() ? object : defaultValue; + } + /** * Determine whether the given object is empty. *

This method supports the following object types. diff --git a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java index 6f1bb001dfc7..e3ed10801c9d 100644 --- a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java @@ -31,6 +31,7 @@ import java.time.LocalDate; import java.time.ZoneId; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Currency; import java.util.Date; @@ -52,6 +53,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.springframework.util.ObjectUtils.getIfEmpty; +import static org.springframework.util.ObjectUtils.getIfNull; import static org.springframework.util.ObjectUtils.isEmpty; /** @@ -111,6 +114,35 @@ void isCompatibleWithThrowsClause() { assertThat(ObjectUtils.isCompatibleWithThrowsClause(new Throwable(), throwable)).isTrue(); } + @Test + void getIfNullObject() { + String value = UUID.randomUUID().toString(); + String backup = UUID.randomUUID().toString(); + assertThat(getIfNull(value, backup)).isEqualTo(value); + assertThat(getIfNull(value, value)).isEqualTo(value); + assertThat(getIfNull(backup, backup)).isEqualTo(backup); + assertThat(getIfNull(null, value)).isEqualTo(value); + assertThat(getIfNull(null, backup)).isEqualTo(backup); + assertThat(getIfNull("null", backup)).isEqualTo("null"); + assertThat(Optional.ofNullable(getIfNull(null, null))).isEmpty(); + } + + @Test + void getIfEmptyObject() { + Collection empty = Collections.emptyList(); + Collection value = List.of(UUID.randomUUID().toString()); + Collection backup = List.of(UUID.randomUUID().toString()); + assertThat(getIfEmpty(value, backup)).isEqualTo(value); + assertThat(getIfEmpty(null, backup)).isEqualTo(backup); + assertThat(getIfEmpty(empty, backup)).isEqualTo(backup); + assertThat(getIfEmpty(value, empty)).isEqualTo(value); + assertThat(getIfEmpty(empty, empty)).isEqualTo(empty); + assertThat(getIfEmpty(backup, backup)).isEqualTo(backup); + assertThat(getIfEmpty(null, empty)).isEqualTo(empty); + assertThat(getIfEmpty(null, backup)).isEqualTo(backup); + assertThat(Optional.ofNullable(getIfEmpty(null, null))).isEmpty(); + } + @Test void isEmptyNull() { assertThat(isEmpty(null)).isTrue(); From 4c2a4f87b09b6b01d2ac37b56aaa710f65706379 Mon Sep 17 00:00:00 2001 From: Vincent Potucek Date: Thu, 13 Mar 2025 14:14:51 +0100 Subject: [PATCH 2/4] add ObjectUtils.getNonNull/getIfNull/getIfEmpty Signed-off-by: Vincent Potucek --- .../org/springframework/util/ObjectUtils.java | 55 ++++++++++--------- .../util/ObjectUtilsTests.java | 53 ++++++++++++------ 2 files changed, 65 insertions(+), 43 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java index 55943bae7fa9..df1a45d347a9 100644 --- a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java @@ -118,46 +118,47 @@ public static boolean isEmpty(@Nullable Object @Nullable [] array) { return (array == null || array.length == 0); } + /** - * Returns the object if it is not {@code null}; otherwise, returns the default value. + * Returns the first non-null element from the provided varargs. * - *

-	 * ObjectUtils.getIfNull(null, null)      = null
-	 * ObjectUtils.getIfNull(null, "")        = ""
-	 * ObjectUtils.getIfNull(null, "zz")      = "zz"
-	 * ObjectUtils.getIfNull("abc", *)        = "abc"
-	 * ObjectUtils.getIfNull(Boolean.TRUE, *) = Boolean.TRUE
-	 * 
+ * @param objects The objects to check for non-null values. + * @param The type of the objects. + * @return An Optional containing the first non-null object, or an empty Optional if all objects are null. + */ + @SafeVarargs + public static Optional getNonNull(@Nullable final T... objects) { + return Optional.ofNullable(objects) + .map(arr -> Arrays.stream(arr).filter(Objects::nonNull).findFirst()) + .orElse(Optional.empty()); + } + + /** + * Returns the object if it is not {@code null}; otherwise, returns the default value. * - * @param the type of the object * @param object the object to test, may be {@code null} * @param defaultValue the default value to return if the object is {@code null}, may be {@code null} - * @return {@code object} if it is not {@code null}; otherwise, {@code defaultValue} + * @param the type of the object + * @return An Optional containing either the object if not null, or the default value wrapped in an Optional. */ - @Nullable - public static T getIfNull(@Nullable final T object, @Nullable final T defaultValue) { - return Objects.nonNull(object) ? object : defaultValue; + public static Optional getIfNull(@Nullable final T object, @Nullable final T defaultValue) { + return Optional.ofNullable(object).or(() -> Optional.ofNullable(defaultValue)); } /** * Returns the collection if it is not {@code null} and not empty; otherwise, returns the default value. * - *
-	 * ObjectUtils.getIfEmpty(List.of("a"), List.of("b"))     			= List.of("a")
-	 * ObjectUtils.getIfEmpty(null, List.of("b"))            			= List.of("b")
-	 * ObjectUtils.getIfEmpty(Collections.emptyList(), List.of("b")) 	= List.of("b")
-	 * ObjectUtils.getIfEmpty(null, null)                    			= null
-	 * 
- * - * @param the type of elements in the collection * @param object the collection to test, may be {@code null} * @param defaultValue the default value to return if the collection is {@code null} or empty, may be {@code null} - * @return {@code object} if it is not {@code null} and not empty; otherwise, {@code defaultValue} - */ - @Nullable - public static Collection getIfEmpty(@Nullable final Collection object, - @Nullable final Collection defaultValue) { - return Objects.nonNull(object) && !object.isEmpty() ? object : defaultValue; + * @param the type of elements in the collection + * @return An Optional containing the collection if not null and not empty, otherwise an Optional of the default + * value. + */ + public static Optional> getIfEmpty(@Nullable final Collection object, + @Nullable final Collection defaultValue) { + return Optional.ofNullable(object) + .filter(collection -> !collection.isEmpty()) + .or(() -> Optional.ofNullable(defaultValue)); } /** diff --git a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java index e3ed10801c9d..bdbd6f069b7b 100644 --- a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java @@ -55,6 +55,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.springframework.util.ObjectUtils.getIfEmpty; import static org.springframework.util.ObjectUtils.getIfNull; +import static org.springframework.util.ObjectUtils.getNonNull; import static org.springframework.util.ObjectUtils.isEmpty; /** @@ -118,13 +119,15 @@ void isCompatibleWithThrowsClause() { void getIfNullObject() { String value = UUID.randomUUID().toString(); String backup = UUID.randomUUID().toString(); - assertThat(getIfNull(value, backup)).isEqualTo(value); - assertThat(getIfNull(value, value)).isEqualTo(value); - assertThat(getIfNull(backup, backup)).isEqualTo(backup); - assertThat(getIfNull(null, value)).isEqualTo(value); - assertThat(getIfNull(null, backup)).isEqualTo(backup); - assertThat(getIfNull("null", backup)).isEqualTo("null"); - assertThat(Optional.ofNullable(getIfNull(null, null))).isEmpty(); + + assertThat(getIfNull(value, backup)).contains(value); + assertThat(getIfNull(value, backup)).contains(value); + assertThat(getIfNull(value, value)).contains(value); + assertThat(getIfNull(backup, backup)).contains(backup); + assertThat(getIfNull(null, value)).contains(value); + assertThat(getIfNull(null, backup)).contains(backup); + assertThat(getIfNull("null", backup)).contains("null"); + assertThat(getIfNull(null, null)).isEmpty(); } @Test @@ -132,15 +135,33 @@ void getIfEmptyObject() { Collection empty = Collections.emptyList(); Collection value = List.of(UUID.randomUUID().toString()); Collection backup = List.of(UUID.randomUUID().toString()); - assertThat(getIfEmpty(value, backup)).isEqualTo(value); - assertThat(getIfEmpty(null, backup)).isEqualTo(backup); - assertThat(getIfEmpty(empty, backup)).isEqualTo(backup); - assertThat(getIfEmpty(value, empty)).isEqualTo(value); - assertThat(getIfEmpty(empty, empty)).isEqualTo(empty); - assertThat(getIfEmpty(backup, backup)).isEqualTo(backup); - assertThat(getIfEmpty(null, empty)).isEqualTo(empty); - assertThat(getIfEmpty(null, backup)).isEqualTo(backup); - assertThat(Optional.ofNullable(getIfEmpty(null, null))).isEmpty(); + + assertThat(getIfEmpty(value, backup)).contains(value); + assertThat(getIfEmpty(null, backup)).contains(backup); + assertThat(getIfEmpty(empty, backup)).contains(backup); + assertThat(getIfEmpty(value, empty)).contains(value); + assertThat(getIfEmpty(empty, empty)).contains(empty); + assertThat(getIfEmpty(backup, backup)).contains(backup); + assertThat(getIfEmpty(null, empty)).contains(empty); + assertThat(getIfEmpty(null, backup)).contains(backup); + assertThat(getIfEmpty(null, null)).isEmpty(); + } + + @Test + void getNonNullObject() { + String value = UUID.randomUUID().toString(); + String backup = UUID.randomUUID().toString(); + + assertThat(getNonNull(backup, value, value)).contains(backup); + assertThat(getNonNull(value, null, backup)).contains(value); + assertThat(getNonNull(backup, value, null)).contains(backup); + assertThat(getNonNull(value, backup)).contains(value); + assertThat(getNonNull(null, null, value)).contains(value); + + String _null = null; + assertThat(getNonNull(null, null, _null)).isEmpty(); + assertThat(getNonNull(null, "null", backup)).contains("null"); + assertThat(getNonNull(null, null)).isEmpty(); } @Test From eef7c29875d8fa90a86fee824244b4bf2c6a9e84 Mon Sep 17 00:00:00 2001 From: Vincent Potucek Date: Fri, 14 Mar 2025 07:34:37 +0100 Subject: [PATCH 3/4] add ObjectUtils.firstNonNull/getIfNull/getIfEmpty Signed-off-by: Vincent Potucek --- .../org/springframework/util/ObjectUtils.java | 2 +- .../util/ObjectUtilsTests.java | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java index df1a45d347a9..1f1171985dcb 100644 --- a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java @@ -127,7 +127,7 @@ public static boolean isEmpty(@Nullable Object @Nullable [] array) { * @return An Optional containing the first non-null object, or an empty Optional if all objects are null. */ @SafeVarargs - public static Optional getNonNull(@Nullable final T... objects) { + public static Optional firstNonNull(@Nullable final T... objects) { return Optional.ofNullable(objects) .map(arr -> Arrays.stream(arr).filter(Objects::nonNull).findFirst()) .orElse(Optional.empty()); diff --git a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java index bdbd6f069b7b..8f06a0697d4e 100644 --- a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java @@ -55,7 +55,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.springframework.util.ObjectUtils.getIfEmpty; import static org.springframework.util.ObjectUtils.getIfNull; -import static org.springframework.util.ObjectUtils.getNonNull; +import static org.springframework.util.ObjectUtils.firstNonNull; import static org.springframework.util.ObjectUtils.isEmpty; /** @@ -148,20 +148,20 @@ void getIfEmptyObject() { } @Test - void getNonNullObject() { + void firstNonNullObject() { String value = UUID.randomUUID().toString(); String backup = UUID.randomUUID().toString(); - assertThat(getNonNull(backup, value, value)).contains(backup); - assertThat(getNonNull(value, null, backup)).contains(value); - assertThat(getNonNull(backup, value, null)).contains(backup); - assertThat(getNonNull(value, backup)).contains(value); - assertThat(getNonNull(null, null, value)).contains(value); + assertThat(firstNonNull(backup, value, value)).contains(backup); + assertThat(firstNonNull(value, null, backup)).contains(value); + assertThat(firstNonNull(backup, value, null)).contains(backup); + assertThat(firstNonNull(value, backup)).contains(value); + assertThat(firstNonNull(null, null, value)).contains(value); String _null = null; - assertThat(getNonNull(null, null, _null)).isEmpty(); - assertThat(getNonNull(null, "null", backup)).contains("null"); - assertThat(getNonNull(null, null)).isEmpty(); + assertThat(firstNonNull(null, null, _null)).isEmpty(); + assertThat(firstNonNull(null, "null", backup)).contains("null"); + assertThat(firstNonNull(null, null)).isEmpty(); } @Test From bf49b439043eeb28259df641455986867f86de61 Mon Sep 17 00:00:00 2001 From: Vincent Potucek Date: Fri, 14 Mar 2025 07:50:39 +0100 Subject: [PATCH 4/4] add ObjectUtils.firstNonNull/getIfNull/getIfEmpty Signed-off-by: Vincent Potucek --- .../org/springframework/util/ObjectUtils.java | 35 +++++++++++++++- .../util/ObjectUtilsTests.java | 40 +++++++++++++++++-- 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java index 1f1171985dcb..ff72a024e9fb 100644 --- a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java @@ -118,7 +118,6 @@ public static boolean isEmpty(@Nullable Object @Nullable [] array) { return (array == null || array.length == 0); } - /** * Returns the first non-null element from the provided varargs. * @@ -133,6 +132,20 @@ public static Optional firstNonNull(@Nullable final T... objects) { .orElse(Optional.empty()); } + /** + * Returns the first non-null element from the provided collection. + * + * @param collection The objects to check for non-null values. + * @param The type of the objects. + * @return An Optional containing the first non-null object, or an empty Optional if all objects are null. + */ + public static Optional firstNonNull(@Nullable final Collection collection) { + if (Objects.isNull(collection) || collection.isEmpty()) { + return Optional.empty(); + } + return collection.stream().filter(Objects::nonNull).findFirst(); + } + /** * Returns the object if it is not {@code null}; otherwise, returns the default value. * @@ -161,6 +174,26 @@ public static Optional> getIfEmpty(@Nullable final Collection< .or(() -> Optional.ofNullable(defaultValue)); } + /** + * Returns the array if it is not {@code null} and not empty; otherwise, returns the default value. + * + * @param object the array to test, may be {@code null} + * @param defaultValue the default value to return if the array is {@code null} or empty, may be {@code null} + * @param the type of elements in the array + * @return An Optional containing the array if not null and not empty, otherwise an Optional of the default + * value. + */ + public static Optional getIfEmpty(@Nullable final T[] object, + @Nullable final T[] defaultValue) { + if (Objects.nonNull(object) && object.length > 0) { + return Optional.of(object); + } + if (Objects.nonNull(defaultValue) && defaultValue.length > 0) { + return Optional.of(defaultValue); + } + return Optional.empty(); + } + /** * Determine whether the given object is empty. *

This method supports the following object types. diff --git a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java index 8f06a0697d4e..9891a47d669d 100644 --- a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java @@ -131,11 +131,12 @@ void getIfNullObject() { } @Test - void getIfEmptyObject() { + void getIfEmptyObjectCollection() { Collection empty = Collections.emptyList(); Collection value = List.of(UUID.randomUUID().toString()); Collection backup = List.of(UUID.randomUUID().toString()); + assertThat(getIfEmpty(value, backup)).contains(value); assertThat(getIfEmpty(value, backup)).contains(value); assertThat(getIfEmpty(null, backup)).contains(backup); assertThat(getIfEmpty(empty, backup)).contains(backup); @@ -144,11 +145,44 @@ void getIfEmptyObject() { assertThat(getIfEmpty(backup, backup)).contains(backup); assertThat(getIfEmpty(null, empty)).contains(empty); assertThat(getIfEmpty(null, backup)).contains(backup); - assertThat(getIfEmpty(null, null)).isEmpty(); } @Test - void firstNonNullObject() { + void getIfEmptyObjectArray() { + String[] empty = new String[0]; + String[] value = {UUID.randomUUID().toString()}; + String[] backup = {UUID.randomUUID().toString()}; + + assertThat(getIfEmpty(value, backup)).contains(value); + assertThat(getIfEmpty(null, backup)).contains(backup); + assertThat(getIfEmpty(empty, backup)).contains(backup); + assertThat(getIfEmpty(value, empty)).contains(value); + assertThat(getIfEmpty(empty, empty)).isEmpty(); + assertThat(getIfEmpty(backup, backup)).contains(backup); + assertThat(getIfEmpty(null, empty)).isEmpty(); + assertThat(getIfEmpty(null, backup)).contains(backup); + } + + @Test + void firstNonNullObjectCollection() { + String value = UUID.randomUUID().toString(); + String backup = UUID.randomUUID().toString(); + + assertThat(ObjectUtils.firstNonNull(Arrays.asList(backup, value, value))).contains(backup); + assertThat(ObjectUtils.firstNonNull(Arrays.asList(value, null, backup))).contains(value); + assertThat(ObjectUtils.firstNonNull(Arrays.asList(backup, value, null))).contains(backup); + assertThat(ObjectUtils.firstNonNull(Arrays.asList(value, backup))).contains(value); + assertThat(ObjectUtils.firstNonNull(Arrays.asList(null, null, value))).contains(value); + + String _null = null; + assertThat(ObjectUtils.firstNonNull(Arrays.asList(null, null, _null))).isEmpty(); + assertThat(ObjectUtils.firstNonNull(Arrays.asList(null, "null", backup))).contains("null"); + assertThat(ObjectUtils.firstNonNull(Arrays.asList(null, null))).isEmpty(); + assertThat(ObjectUtils.firstNonNull(Collections.emptyList())).isEmpty(); + } + + @Test + void firstNonNullObjectArray() { String value = UUID.randomUUID().toString(); String backup = UUID.randomUUID().toString();