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

commit 8ddebc231eb63d4e00ba3c04d108f2569c521561
Author: Gary Gregory <garydgreg...@gmail.com>
AuthorDate: Tue Apr 2 14:41:18 2024 -0400

    Add T ArrayUtils.arraycopy(T, int, int, int, Function) fluent style
    
    Add T ArrayUtils.arraycopy(T, int, int, int, Supplier) fluent style
---
 src/changes/changes.xml                            |  2 +
 .../java/org/apache/commons/lang3/ArrayUtils.java  | 70 +++++++++++++++-------
 .../apache/commons/lang3/reflect/MethodUtils.java  | 12 ++--
 .../org/apache/commons/lang3/text/StrBuilder.java  | 14 ++---
 4 files changed, 61 insertions(+), 37 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 20cb0d73d..f1a362703 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -57,6 +57,8 @@ The <action> type attribute can be add,update,fix,remove.
     <action issue="LANG-1724" type="add" dev="ggregory" due-to="Gary 
Gregory">Add Streams.nonNull(T), non-varargs variant.</action>
     <action issue="LANG-1724" type="add" dev="ggregory" due-to="Gary 
Gregory">Add ArrayUtils.nullTo(T[], T[]).</action>
     <action issue="LANG-1724" type="add" dev="ggregory" due-to="Gary 
Gregory">Add T ArrayUtils.arraycopy(T, int, T, int, int) fluent style.</action>
+    <action issue="LANG-1724" type="add" dev="ggregory" due-to="Gary 
Gregory">Add T ArrayUtils.arraycopy(T, int, int, int, Function) fluent 
style.</action>
+    <action issue="LANG-1724" type="add" dev="ggregory" due-to="Gary 
Gregory">Add T ArrayUtils.arraycopy(T, int, int, int, Supplier) fluent 
style.</action>
     <!-- FIX -->
     <action                   type="fix" dev="ggregory" due-to="Miklós Karakó, 
Gary Gregory">Improve Javadoc in ExceptionUtils #1136.</action>
     <action                   type="fix" dev="ggregory" due-to="Saiharshith 
Karuneegar Ramesh, Gary Gregory">Fixed two non-deterministic tests in 
EnumUtilsTest.java #1131.</action>
diff --git a/src/main/java/org/apache/commons/lang3/ArrayUtils.java 
b/src/main/java/org/apache/commons/lang3/ArrayUtils.java
index 7faf9cc03..718c20ffb 100644
--- a/src/main/java/org/apache/commons/lang3/ArrayUtils.java
+++ b/src/main/java/org/apache/commons/lang3/ArrayUtils.java
@@ -29,6 +29,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Random;
 import java.util.concurrent.ThreadLocalRandom;
+import java.util.function.Function;
 import java.util.function.IntFunction;
 import java.util.function.Supplier;
 
@@ -659,8 +660,7 @@ public class ArrayUtils {
         if (index > length || index < 0) {
             throw new IndexOutOfBoundsException("Index: " + index + ", Length: 
" + length);
         }
-        final Object result = Array.newInstance(clazz, length + 1);
-        System.arraycopy(array, 0, result, 0, index);
+        final Object result = arraycopy(array, 0, 0, index, () -> 
Array.newInstance(clazz, length + 1));
         Array.set(result, index, element);
         if (index < length) {
             System.arraycopy(array, index, result, index + 1, length - index);
@@ -1114,21 +1114,18 @@ public class ArrayUtils {
             return clone(array1);
         }
         final Class<T> type1 = getComponentType(array1);
-        final T[] joinedArray = newInstance(type1, array1.length + 
array2.length);
-        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
+        final T[] joinedArray = arraycopy(array1, 0, 0, array1.length, () -> 
newInstance(type1, array1.length + array2.length));
         try {
             System.arraycopy(array2, 0, joinedArray, array1.length, 
array2.length);
         } catch (final ArrayStoreException ase) {
             // Check if problem was due to incompatible types
             /*
-             * We do this here, rather than before the copy because:
-             * - it would be a wasted check most of the time
-             * - safer, in case check turns out to be too strict
+             * We do this here, rather than before the copy because: - it 
would be a wasted check most of the time - safer, in case check turns out to be 
too
+             * strict
              */
             final Class<?> type2 = array2.getClass().getComponentType();
             if (!type1.isAssignableFrom(type2)) {
-                throw new IllegalArgumentException("Cannot store " + 
type2.getName() + " in an array of "
-                        + type1.getName(), ase);
+                throw new IllegalArgumentException("Cannot store " + 
type2.getName() + " in an array of " + type1.getName(), ase);
             }
             throw ase; // No, so rethrow original
         }
@@ -1395,6 +1392,46 @@ public class ArrayUtils {
         return dest;
     }
 
+    /**
+     * A fluent version of {@link System#arraycopy(Object, int, Object, int, 
int)} that returns the destination array.
+     *
+     * @param <T>       the type.
+     * @param source    the source array.
+     * @param sourcePos starting position in the source array.
+     * @param destPos   starting position in the destination data.
+     * @param length    the number of array elements to be copied.
+     * @param allocator allocates the array to populate and return.
+     * @return dest
+     * @throws IndexOutOfBoundsException if copying would cause access of data 
outside array bounds.
+     * @throws ArrayStoreException       if an element in the <code>src</code> 
array could not be stored into the <code>dest</code> array because of a type
+     *                                   mismatch.
+     * @throws NullPointerException      if either <code>src</code> or 
<code>dest</code> is <code>null</code>.
+     * @since 3.15.0
+     */
+    public static <T> T arraycopy(final T source, final int sourcePos, final 
int destPos, final int length, final Function<Integer, T> allocator) {
+        return arraycopy(source, sourcePos, allocator.apply(length), destPos, 
length);
+    }
+
+    /**
+     * A fluent version of {@link System#arraycopy(Object, int, Object, int, 
int)} that returns the destination array.
+     *
+     * @param <T>       the type.
+     * @param source    the source array.
+     * @param sourcePos starting position in the source array.
+     * @param destPos   starting position in the destination data.
+     * @param length    the number of array elements to be copied.
+     * @param allocator allocates the array to populate and return.
+     * @return dest
+     * @throws IndexOutOfBoundsException if copying would cause access of data 
outside array bounds.
+     * @throws ArrayStoreException       if an element in the <code>src</code> 
array could not be stored into the <code>dest</code> array because of a type
+     *                                   mismatch.
+     * @throws NullPointerException      if either <code>src</code> or 
<code>dest</code> is <code>null</code>.
+     * @since 3.15.0
+     */
+    public static <T> T arraycopy(final T source, final int sourcePos, final 
int destPos, final int length, final Supplier<T> allocator) {
+        return arraycopy(source, sourcePos, allocator.get(), destPos, length);
+    }
+
     /**
      * Clones an array or returns {@code null}.
      * <p>
@@ -8163,9 +8200,7 @@ public class ArrayUtils {
         if (newSize <= 0) {
             return EMPTY_INT_ARRAY;
         }
-
-        final int[] subarray = new int[newSize];
-        return arraycopy(array, startIndexInclusive, subarray, 0, newSize);
+        return arraycopy(array, startIndexInclusive, 0, newSize, int[]::new);
     }
 
     /**
@@ -8203,9 +8238,7 @@ public class ArrayUtils {
         if (newSize <= 0) {
             return EMPTY_LONG_ARRAY;
         }
-
-        final long[] subarray = new long[newSize];
-        return arraycopy(array, startIndexInclusive, subarray, 0, newSize);
+        return arraycopy(array, startIndexInclusive, 0, newSize, long[]::new);
     }
 
     /**
@@ -8243,9 +8276,7 @@ public class ArrayUtils {
         if (newSize <= 0) {
             return EMPTY_SHORT_ARRAY;
         }
-
-        final short[] subarray = new short[newSize];
-        return arraycopy(array, startIndexInclusive, subarray, 0, newSize);
+        return arraycopy(array, startIndexInclusive, 0, newSize, short[]::new);
     }
 
     /**
@@ -8293,8 +8324,7 @@ public class ArrayUtils {
         if (newSize <= 0) {
             return newInstance(type, 0);
         }
-        final T[] subarray = newInstance(type, newSize);
-        return arraycopy(array, startIndexInclusive, subarray, 0, newSize);
+        return arraycopy(array, startIndexInclusive, 0, newSize, () -> 
newInstance(type, newSize));
     }
 
     /**
diff --git a/src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java 
b/src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java
index 4de2b1d7f..86215b468 100644
--- a/src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java
+++ b/src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java
@@ -568,25 +568,23 @@ public class MethodUtils {
      * @since 3.5
      */
     static Object[] getVarArgs(final Object[] args, final Class<?>[] 
methodParameterTypes) {
-        if (args.length == methodParameterTypes.length && (args[args.length - 
1] == null ||
-                args[args.length - 
1].getClass().equals(methodParameterTypes[methodParameterTypes.length - 1]))) {
+        if (args.length == methodParameterTypes.length
+                && (args[args.length - 1] == null || args[args.length - 
1].getClass().equals(methodParameterTypes[methodParameterTypes.length - 1]))) {
             // The args array is already in the canonical form for the method.
             return args;
         }
 
         // Construct a new array matching the method's declared parameter 
types.
-        final Object[] newArgs = new Object[methodParameterTypes.length];
-
         // Copy the normal (non-varargs) parameters
-        System.arraycopy(args, 0, newArgs, 0, methodParameterTypes.length - 1);
+        final Object[] newArgs = ArrayUtils.arraycopy(args, 0, 0, 
methodParameterTypes.length - 1, () -> new Object[methodParameterTypes.length]);
 
         // Construct a new array for the variadic parameters
         final Class<?> varArgComponentType = 
methodParameterTypes[methodParameterTypes.length - 1].getComponentType();
         final int varArgLength = args.length - methodParameterTypes.length + 1;
 
-        Object varArgsArray = 
Array.newInstance(ClassUtils.primitiveToWrapper(varArgComponentType), 
varArgLength);
         // Copy the variadic arguments into the varargs array.
-        System.arraycopy(args, methodParameterTypes.length - 1, varArgsArray, 
0, varArgLength);
+        Object varArgsArray = ArrayUtils.arraycopy(args, 
methodParameterTypes.length - 1, 0, varArgLength,
+                s -> 
Array.newInstance(ClassUtils.primitiveToWrapper(varArgComponentType), 
varArgLength));
 
         if (varArgComponentType.isPrimitive()) {
             // unbox from wrapper type to primitive type
diff --git a/src/main/java/org/apache/commons/lang3/text/StrBuilder.java 
b/src/main/java/org/apache/commons/lang3/text/StrBuilder.java
index cf53a7baf..e8a91f4ee 100644
--- a/src/main/java/org/apache/commons/lang3/text/StrBuilder.java
+++ b/src/main/java/org/apache/commons/lang3/text/StrBuilder.java
@@ -1832,9 +1832,7 @@ public class StrBuilder implements CharSequence, 
Appendable, Serializable, Build
      */
     public StrBuilder ensureCapacity(final int capacity) {
         if (capacity > buffer.length) {
-            final char[] old = buffer;
-            buffer = new char[capacity * 2];
-            System.arraycopy(old, 0, buffer, 0, size);
+            buffer = ArrayUtils.arraycopy(buffer, 0, 0, size, () -> new 
char[capacity * 2]);
         }
         return this;
     }
@@ -2468,9 +2466,7 @@ public class StrBuilder implements CharSequence, 
Appendable, Serializable, Build
      */
     public StrBuilder minimizeCapacity() {
         if (buffer.length > length()) {
-            final char[] old = buffer;
-            buffer = new char[length()];
-            System.arraycopy(old, 0, buffer, 0, size);
+            buffer = ArrayUtils.arraycopy(buffer, 0, 0, size, () -> new 
char[length()]);
         }
         return this;
     }
@@ -2937,8 +2933,7 @@ public class StrBuilder implements CharSequence, 
Appendable, Serializable, Build
         if (size == 0) {
             return ArrayUtils.EMPTY_CHAR_ARRAY;
         }
-        final char[] chars = new char[size];
-        return ArrayUtils.arraycopy(buffer, 0, chars, 0, size);
+        return ArrayUtils.arraycopy(buffer, 0, 0, size, char[]::new);
     }
 
     /**
@@ -2957,8 +2952,7 @@ public class StrBuilder implements CharSequence, 
Appendable, Serializable, Build
         if (len == 0) {
             return ArrayUtils.EMPTY_CHAR_ARRAY;
         }
-        final char[] chars = new char[len];
-        return ArrayUtils.arraycopy(buffer, startIndex, chars, 0, len);
+        return ArrayUtils.arraycopy(buffer, startIndex, 0, len, char[]::new);
     }
 
     /**

Reply via email to