From 3cab3898f4cd8495cf7e6183d0ffceaaca68acb3 Mon Sep 17 00:00:00 2001
From: Bindul Bhowmik
Date: Mon, 28 Dec 2020 00:37:41 -0700
Subject: [PATCH 1/4] [LANG-1634] Add ObjectUtils #applyIfNonNull and
#applyFirstNonNull
Utility methods that take a java.util.function.Consumer and possibly
null value(s). The consumer is invoked if the value is not null or with
the first non-null value, respectively.
---
.../org/apache/commons/lang3/ObjectUtils.java | 57 +++++++++++++++++++
.../apache/commons/lang3/ObjectUtilsTest.java | 36 ++++++++++++
2 files changed, 93 insertions(+)
diff --git a/src/main/java/org/apache/commons/lang3/ObjectUtils.java b/src/main/java/org/apache/commons/lang3/ObjectUtils.java
index 8461ee9b167..940845ed900 100644
--- a/src/main/java/org/apache/commons/lang3/ObjectUtils.java
+++ b/src/main/java/org/apache/commons/lang3/ObjectUtils.java
@@ -27,6 +27,7 @@
import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;
+import java.util.function.Consumer;
import java.util.function.Supplier;
import org.apache.commons.lang3.exception.CloneFailedException;
@@ -226,6 +227,62 @@ public static boolean anyNotNull(final Object... values) {
return firstNonNull(values) != null;
}
+ /**
+ *
+ * Invokes the given {@code consumer's} {@link Consumer#accept(Object)} with the first {@code non-null} value from
+ * {@code objects}. If all the values are null, the consumer is not invoked.
+ *
+ *
+ *
+ * The caller is responsible for thread-safety and exception handling of consumer.
+ *
+ *
+ *
+ * ObjectUtils.applyIfNonNull(bean::setValue, null) - setValue not invoked
+ * ObjectUtils.applyIfNonNull(bean::setValue, null, "abc", "def") - setValue invoked with "abc"
+ * ObjectUtils.applyIfNonNull(v -> bean.setValue(v), "abc") - setValue invoked with "abc"
+ *
+ *
+ * @param the type of the object
+ * @param objects the values to test, may be {@code null} or empty
+ * @param consumer the consumer operation to invoke with the first non-null {@code objects}.
+ * @see #firstNonNull(Object...)
+ * @see #applyIfNonNull(Consumer, Object)
+ * @since 3.12
+ */
+ @SafeVarargs
+ public static void applyFirstNonNull(final Consumer consumer, final T... objects) {
+ applyIfNonNull(consumer, firstNonNull(objects));
+ }
+
+ /**
+ *
+ * Invokes the given {@code consumer's} {@link Consumer#accept(Object)} with the {@code object} if it is
+ * {@code non-null}, otherwise the consumer is not invoked.
+ *
+ *
+ *
+ * The caller is responsible for thread-safety and exception handling of consumer.
+ *
+ *
+ *
+ * ObjectUtils.applyIfNonNull(bean::setValue, null) - setValue not invoked
+ * ObjectUtils.applyIfNonNull(bean::setValue, "abc") - setValue invoked with "abc"
+ * ObjectUtils.applyIfNonNull(v -> bean.setValue(v), "abc") - setValue invoked with "abc"
+ *
+ *
+ * @param the type of the object
+ * @param object the {@code Object} to test, may be {@code null}
+ * @param consumer the consumer operation to invoke with {@code object} if it is {@code non-null}
+ * @see #applyFirstNonNull(Consumer, Object...)
+ * @since 3.12
+ */
+ public static void applyIfNonNull(final Consumer consumer, final T object) {
+ if (object != null) {
+ consumer.accept(object);
+ }
+ }
+
// cloning
//-----------------------------------------------------------------------
/**
diff --git a/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java b/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java
index 3efafe70ab6..7a997917dfc 100644
--- a/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java
@@ -245,6 +245,33 @@ public void testEquals() {
assertTrue(ObjectUtils.equals(FOO, FOO), "ObjectUtils.equals(\"foo\", \"foo\") returned false");
}
+ @Test
+ public void testApplyIfNonNull() {
+ final ApplyIfNonNullBean bean = new ApplyIfNonNullBean();
+ bean.setValue(FOO);
+
+ ObjectUtils.applyIfNonNull(bean::setValue, null);
+ assertEquals(FOO, bean.getValue());
+
+ ObjectUtils.applyIfNonNull(bean::setValue, BAR);
+ assertEquals(BAR, bean.getValue());
+
+ ObjectUtils.applyIfNonNull(v -> bean.setValue(v), FOO);
+ assertEquals(FOO, bean.getValue());
+ }
+
+ @Test
+ public void testApplyFirstNonNull() {
+ final ApplyIfNonNullBean bean = new ApplyIfNonNullBean();
+ bean.setValue(FOO);
+
+ ObjectUtils.applyFirstNonNull(bean::setValue, null, null, null);
+ assertEquals(FOO, bean.getValue());
+
+ ObjectUtils.applyFirstNonNull(bean::setValue, null, null, BAR, FOO, null);
+ assertEquals(BAR, bean.getValue());
+ }
+
@Test
public void testNotEqual() {
assertFalse(ObjectUtils.notEqual(null, null), "ObjectUtils.notEqual(null, null) returned false");
@@ -764,4 +791,13 @@ public int compare(final CharSequence o1, final CharSequence o2) {
}
+ static final class ApplyIfNonNullBean {
+ private String value;
+ public String getValue() {
+ return value;
+ }
+ public void setValue(String value) {
+ this.value = value;
+ }
+ }
}
From 15d0642385adbc6542fca87f4626876375160ae3 Mon Sep 17 00:00:00 2001
From: Bindul Bhowmik
Date: Mon, 28 Dec 2020 14:39:56 -0700
Subject: [PATCH 2/4] Correct method name in Javadoc.
---
src/main/java/org/apache/commons/lang3/ObjectUtils.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/main/java/org/apache/commons/lang3/ObjectUtils.java b/src/main/java/org/apache/commons/lang3/ObjectUtils.java
index 940845ed900..c4d30274f92 100644
--- a/src/main/java/org/apache/commons/lang3/ObjectUtils.java
+++ b/src/main/java/org/apache/commons/lang3/ObjectUtils.java
@@ -238,9 +238,9 @@ public static boolean anyNotNull(final Object... values) {
*
*
*
- * ObjectUtils.applyIfNonNull(bean::setValue, null) - setValue not invoked
- * ObjectUtils.applyIfNonNull(bean::setValue, null, "abc", "def") - setValue invoked with "abc"
- * ObjectUtils.applyIfNonNull(v -> bean.setValue(v), "abc") - setValue invoked with "abc"
+ * ObjectUtils.applyFirstNonNull(bean::setValue, null) - setValue not invoked
+ * ObjectUtils.applyFirstNonNull(bean::setValue, null, "abc", "def") - setValue invoked with "abc"
+ * ObjectUtils.applyFirstNonNull(v -> bean.setValue(v), "abc") - setValue invoked with "abc"
*
*
* @param the type of the object
From 25f5effcdf4d3f9127febd2e5b0eabb710a17f01 Mon Sep 17 00:00:00 2001
From: Bindul Bhowmik
Date: Tue, 29 Dec 2020 13:29:20 -0700
Subject: [PATCH 3/4] Changes for review comments on PR apache/commons-lang#684
- Changed method names from applyIfNonNull -> acceptIfNonNull; and
applyFirstNonNull -> acceptFirstNonNull
- Changed parameter order
---
.../org/apache/commons/lang3/ObjectUtils.java | 31 ++++++++++---------
.../apache/commons/lang3/ObjectUtilsTest.java | 21 +++++++------
2 files changed, 27 insertions(+), 25 deletions(-)
diff --git a/src/main/java/org/apache/commons/lang3/ObjectUtils.java b/src/main/java/org/apache/commons/lang3/ObjectUtils.java
index c4d30274f92..a5028507907 100644
--- a/src/main/java/org/apache/commons/lang3/ObjectUtils.java
+++ b/src/main/java/org/apache/commons/lang3/ObjectUtils.java
@@ -229,8 +229,9 @@ public static boolean anyNotNull(final Object... values) {
/**
*
- * Invokes the given {@code consumer's} {@link Consumer#accept(Object)} with the first {@code non-null} value from
- * {@code objects}. If all the values are null, the consumer is not invoked.
+ * Calls the given {@code consumer's} {@link Consumer#accept(Object)} method with the first {@code non-null} value
+ * from {@code objects}. If all the values are null, the consumer is not invoked. This is equivalent to the call
+ * {@code ObjectUtils.acceptIfNonNull(ObjectUtils.firstNonNull(objects), consumer)}
*
*
*
@@ -238,27 +239,27 @@ public static boolean anyNotNull(final Object... values) {
*
*
*
- * ObjectUtils.applyFirstNonNull(bean::setValue, null) - setValue not invoked
- * ObjectUtils.applyFirstNonNull(bean::setValue, null, "abc", "def") - setValue invoked with "abc"
- * ObjectUtils.applyFirstNonNull(v -> bean.setValue(v), "abc") - setValue invoked with "abc"
+ * ObjectUtils.acceptFirstNonNull(bean::setValue, null) - setValue not invoked
+ * ObjectUtils.acceptFirstNonNull(bean::setValue, null, "abc", "def") - setValue invoked with "abc"
+ * ObjectUtils.acceptFirstNonNull(v -> bean.setValue(v), "abc") - setValue invoked with "abc"
*
*
* @param the type of the object
* @param objects the values to test, may be {@code null} or empty
* @param consumer the consumer operation to invoke with the first non-null {@code objects}.
* @see #firstNonNull(Object...)
- * @see #applyIfNonNull(Consumer, Object)
+ * @see #acceptIfNonNull(Object, Consumer)
* @since 3.12
*/
@SafeVarargs
- public static void applyFirstNonNull(final Consumer consumer, final T... objects) {
- applyIfNonNull(consumer, firstNonNull(objects));
+ public static void acceptFirstNonNull(final Consumer consumer, final T... objects) {
+ acceptIfNonNull(firstNonNull(objects), consumer);
}
/**
*
- * Invokes the given {@code consumer's} {@link Consumer#accept(Object)} with the {@code object} if it is
- * {@code non-null}, otherwise the consumer is not invoked.
+ * Calls the given {@code consumer's} {@link Consumer#accept(Object)} method with the {@code object} if it is
+ * {@code non-null}.
*
*
*
@@ -266,18 +267,18 @@ public static void applyFirstNonNull(final Consumer consumer, final T...
*
*
*
- * ObjectUtils.applyIfNonNull(bean::setValue, null) - setValue not invoked
- * ObjectUtils.applyIfNonNull(bean::setValue, "abc") - setValue invoked with "abc"
- * ObjectUtils.applyIfNonNull(v -> bean.setValue(v), "abc") - setValue invoked with "abc"
+ * ObjectUtils.acceptIfNonNull(null, bean::setValue) - setValue not invoked
+ * ObjectUtils.acceptIfNonNull("abc", bean::setValue) - setValue invoked with "abc"
+ * ObjectUtils.acceptIfNonNull("abc", v -> bean.setValue(v)) - setValue invoked with "abc"
*
*
* @param the type of the object
* @param object the {@code Object} to test, may be {@code null}
* @param consumer the consumer operation to invoke with {@code object} if it is {@code non-null}
- * @see #applyFirstNonNull(Consumer, Object...)
+ * @see #acceptFirstNonNull(Consumer, Object...)
* @since 3.12
*/
- public static void applyIfNonNull(final Consumer consumer, final T object) {
+ public static void acceptIfNonNull(final T object, final Consumer consumer) {
if (object != null) {
consumer.accept(object);
}
diff --git a/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java b/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java
index 7a997917dfc..11eb563dcf7 100644
--- a/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java
@@ -40,6 +40,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.function.Supplier;
@@ -246,30 +247,30 @@ public void testEquals() {
}
@Test
- public void testApplyIfNonNull() {
+ public void testAcceptFirstNonNull() {
final ApplyIfNonNullBean bean = new ApplyIfNonNullBean();
bean.setValue(FOO);
- ObjectUtils.applyIfNonNull(bean::setValue, null);
+ ObjectUtils.acceptFirstNonNull(bean::setValue, null, null, null);
assertEquals(FOO, bean.getValue());
- ObjectUtils.applyIfNonNull(bean::setValue, BAR);
+ ObjectUtils.acceptFirstNonNull(bean::setValue, null, null, BAR, FOO, null);
assertEquals(BAR, bean.getValue());
-
- ObjectUtils.applyIfNonNull(v -> bean.setValue(v), FOO);
- assertEquals(FOO, bean.getValue());
}
@Test
- public void testApplyFirstNonNull() {
+ public void testAcceptIfNonNull() {
final ApplyIfNonNullBean bean = new ApplyIfNonNullBean();
bean.setValue(FOO);
- ObjectUtils.applyFirstNonNull(bean::setValue, null, null, null);
+ ObjectUtils.acceptIfNonNull(null, bean::setValue);
assertEquals(FOO, bean.getValue());
- ObjectUtils.applyFirstNonNull(bean::setValue, null, null, BAR, FOO, null);
+ ObjectUtils.acceptIfNonNull(BAR, bean::setValue);
assertEquals(BAR, bean.getValue());
+
+ ObjectUtils.acceptIfNonNull(FOO, v -> bean.setValue(v));
+ assertEquals(FOO, bean.getValue());
}
@Test
@@ -797,7 +798,7 @@ public String getValue() {
return value;
}
public void setValue(String value) {
- this.value = value;
+ this.value = Objects.requireNonNull(value, "value");
}
}
}
From adf1e04fb5d614ce6417ce166a90246162f8de60 Mon Sep 17 00:00:00 2001
From: Bindul Bhowmik
Date: Tue, 29 Dec 2020 13:31:59 -0700
Subject: [PATCH 4/4] Eat your own dog food for LANG-1634
Update a few existing classes to use ObjectUtils#acceptIfNonNull(Object,
Consumer)
---
.../org/apache/commons/lang3/StringUtils.java | 20 +++++--------------
.../builder/ReflectionToStringBuilder.java | 5 ++---
.../lang3/concurrent/BasicThreadFactory.java | 13 ++++--------
3 files changed, 11 insertions(+), 27 deletions(-)
diff --git a/src/main/java/org/apache/commons/lang3/StringUtils.java b/src/main/java/org/apache/commons/lang3/StringUtils.java
index 478139e37a7..f0874c267ac 100644
--- a/src/main/java/org/apache/commons/lang3/StringUtils.java
+++ b/src/main/java/org/apache/commons/lang3/StringUtils.java
@@ -4391,16 +4391,12 @@ public static String join(final Iterator> iterator, final char separator) {
// two or more elements
final StringBuilder buf = new StringBuilder(STRING_BUILDER_SIZE); // Java default is 16, probably too small
- if (first != null) {
- buf.append(first);
- }
+ ObjectUtils.acceptIfNonNull(first, buf::append);
while (iterator.hasNext()) {
buf.append(separator);
final Object obj = iterator.next();
- if (obj != null) {
- buf.append(obj);
- }
+ ObjectUtils.acceptIfNonNull(obj, buf::append);
}
return buf.toString();
@@ -4435,18 +4431,12 @@ public static String join(final Iterator> iterator, final String separator) {
// two or more elements
final StringBuilder buf = new StringBuilder(STRING_BUILDER_SIZE); // Java default is 16, probably too small
- if (first != null) {
- buf.append(first);
- }
+ ObjectUtils.acceptIfNonNull(first, buf::append);
while (iterator.hasNext()) {
- if (separator != null) {
- buf.append(separator);
- }
+ ObjectUtils.acceptIfNonNull(separator, buf::append);
final Object obj = iterator.next();
- if (obj != null) {
- buf.append(obj);
- }
+ ObjectUtils.acceptIfNonNull(obj, buf::append);
}
return buf.toString();
}
diff --git a/src/main/java/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java b/src/main/java/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java
index 63ad959d181..c34829a17f5 100644
--- a/src/main/java/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java
+++ b/src/main/java/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java
@@ -29,6 +29,7 @@
import org.apache.commons.lang3.ArraySorter;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ClassUtils;
+import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.Validate;
/**
@@ -413,9 +414,7 @@ static String[] toNoNullStringArray(final Collection collection) {
static String[] toNoNullStringArray(final Object[] array) {
final List list = new ArrayList<>(array.length);
for (final Object e : array) {
- if (e != null) {
- list.add(e.toString());
- }
+ ObjectUtils.acceptIfNonNull(e, o -> list.add(e.toString()));
}
return list.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
}
diff --git a/src/main/java/org/apache/commons/lang3/concurrent/BasicThreadFactory.java b/src/main/java/org/apache/commons/lang3/concurrent/BasicThreadFactory.java
index 631f2e4653a..0422e7e95c5 100644
--- a/src/main/java/org/apache/commons/lang3/concurrent/BasicThreadFactory.java
+++ b/src/main/java/org/apache/commons/lang3/concurrent/BasicThreadFactory.java
@@ -20,6 +20,7 @@
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicLong;
+import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.Validate;
/**
@@ -224,17 +225,11 @@ private void initializeThread(final Thread thread) {
thread.setName(String.format(getNamingPattern(), count));
}
- if (getUncaughtExceptionHandler() != null) {
- thread.setUncaughtExceptionHandler(getUncaughtExceptionHandler());
- }
+ ObjectUtils.acceptIfNonNull(getUncaughtExceptionHandler(), thread::setUncaughtExceptionHandler);
- if (getPriority() != null) {
- thread.setPriority(getPriority().intValue());
- }
+ ObjectUtils.acceptIfNonNull(getPriority(), p -> thread.setPriority(p.intValue()));
- if (getDaemonFlag() != null) {
- thread.setDaemon(getDaemonFlag().booleanValue());
- }
+ ObjectUtils.acceptIfNonNull(getDaemonFlag(), d -> thread.setDaemon(d.booleanValue()));
}
/**