Skip to content

Commit 885499c

Browse files
committed
LANG-1707 add concat methods to ArrayUtils
1 parent c4ea2b0 commit 885499c

3 files changed

Lines changed: 484 additions & 0 deletions

File tree

pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@
7777
<version>5.6.0</version>
7878
<scope>test</scope>
7979
</dependency>
80+
<dependency>
81+
<groupId>org.mockito</groupId>
82+
<artifactId>mockito-inline</artifactId>
83+
<version>${commons.mockito.version}</version>
84+
</dependency>
8085
<!-- For Javadoc links -->
8186
<dependency>
8287
<groupId>org.apache.commons</groupId>

src/main/java/org/apache/commons/lang3/ArrayUtils.java

Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9332,6 +9332,271 @@ public static String[] toStringArray(final Object[] array, final String valueFor
93329332
return map(array, String.class, e -> Objects.toString(e, valueForNullElements));
93339333
}
93349334

9335+
/**
9336+
* Concatenates multiple boolean arrays into a single array.
9337+
* <p>
9338+
* This method combines all input arrays in the order they are provided,
9339+
* creating a new array that contains all elements from the input arrays.
9340+
* The resulting array length is the sum of lengths of all non-null input arrays.
9341+
* </p>
9342+
*
9343+
* @param arrays the arrays to concatenate. Can be empty, contain nulls,
9344+
* or be null itself (treated as empty varargs).
9345+
* @return a new boolean array containing all elements from the input arrays
9346+
* in the order they appear, or an empty array if no elements are present.
9347+
* @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
9348+
* @since 3.21.0
9349+
*/
9350+
public static boolean[] concat(boolean[]... arrays) {
9351+
int totalLength = 0;
9352+
for (boolean[] array : arrays) {
9353+
totalLength = addExact(totalLength, array);
9354+
}
9355+
final boolean[] result = new boolean[totalLength];
9356+
int currentPos = 0;
9357+
for (boolean[] array : arrays) {
9358+
if (array != null && array.length > 0) {
9359+
System.arraycopy(array, 0, result, currentPos, array.length);
9360+
currentPos += array.length;
9361+
}
9362+
}
9363+
return result;
9364+
}
9365+
9366+
/**
9367+
* Concatenates multiple byte arrays into a single array.
9368+
* <p>
9369+
* This method combines all input arrays in the order they are provided,
9370+
* creating a new array that contains all elements from the input arrays.
9371+
* The resulting array length is the sum of lengths of all non-null input arrays.
9372+
* </p>
9373+
*
9374+
* @param arrays the arrays to concatenate. Can be empty, contain nulls,
9375+
* or be null itself (treated as empty varargs).
9376+
* @return a new byte array containing all elements from the input arrays
9377+
* in the order they appear, or an empty array if no elements are present.
9378+
* @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
9379+
* @since 3.21.0
9380+
*/
9381+
public static byte[] concat(byte[]... arrays) {
9382+
int totalLength = 0;
9383+
for (byte[] array : arrays) {
9384+
totalLength = addExact(totalLength, array);
9385+
}
9386+
final byte[] result = new byte[totalLength];
9387+
int currentPos = 0;
9388+
for (byte[] array : arrays) {
9389+
if (array != null && array.length > 0) {
9390+
System.arraycopy(array, 0, result, currentPos, array.length);
9391+
currentPos += array.length;
9392+
}
9393+
}
9394+
return result;
9395+
}
9396+
9397+
/**
9398+
* Concatenates multiple char arrays into a single array.
9399+
* <p>
9400+
* This method combines all input arrays in the order they are provided,
9401+
* creating a new array that contains all elements from the input arrays.
9402+
* The resulting array length is the sum of lengths of all non-null input arrays.
9403+
* </p>
9404+
*
9405+
* @param arrays the arrays to concatenate. Can be empty, contain nulls,
9406+
* or be null itself (treated as empty varargs).
9407+
* @return a new char array containing all elements from the input arrays
9408+
* in the order they appear, or an empty array if no elements are present.
9409+
* @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
9410+
* @since 3.21.0
9411+
*/
9412+
public static char[] concat(char[]... arrays) {
9413+
int totalLength = 0;
9414+
for (char[] array : arrays) {
9415+
totalLength = addExact(totalLength, array);
9416+
}
9417+
final char[] result = new char[totalLength];
9418+
int currentPos = 0;
9419+
for (char[] array : arrays) {
9420+
if (array != null && array.length > 0) {
9421+
System.arraycopy(array, 0, result, currentPos, array.length);
9422+
currentPos += array.length;
9423+
}
9424+
}
9425+
return result;
9426+
}
9427+
9428+
/**
9429+
* Concatenates multiple double arrays into a single array.
9430+
* <p>
9431+
* This method combines all input arrays in the order they are provided,
9432+
* creating a new array that contains all elements from the input arrays.
9433+
* The resulting array length is the sum of lengths of all non-null input arrays.
9434+
* </p>
9435+
*
9436+
* @param arrays the arrays to concatenate. Can be empty, contain nulls,
9437+
* or be null itself (treated as empty varargs).
9438+
* @return a new double array containing all elements from the input arrays
9439+
* in the order they appear, or an empty array if no elements are present.
9440+
* @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
9441+
* @since 3.21.0
9442+
*/
9443+
public static double[] concat(double[]... arrays) {
9444+
int totalLength = 0;
9445+
for (double[] array : arrays) {
9446+
totalLength = addExact(totalLength, array);
9447+
}
9448+
final double[] result = new double[totalLength];
9449+
int currentPos = 0;
9450+
for (double[] array : arrays) {
9451+
if (array != null && array.length > 0) {
9452+
System.arraycopy(array, 0, result, currentPos, array.length);
9453+
currentPos += array.length;
9454+
}
9455+
}
9456+
return result;
9457+
}
9458+
9459+
/**
9460+
* Concatenates multiple float arrays into a single array.
9461+
* <p>
9462+
* This method combines all input arrays in the order they are provided,
9463+
* creating a new array that contains all elements from the input arrays.
9464+
* The resulting array length is the sum of lengths of all non-null input arrays.
9465+
* </p>
9466+
*
9467+
* @param arrays the arrays to concatenate. Can be empty, contain nulls,
9468+
* or be null itself (treated as empty varargs).
9469+
* @return a new float array containing all elements from the input arrays
9470+
* in the order they appear, or an empty array if no elements are present.
9471+
* @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
9472+
* @since 3.21.0
9473+
*/
9474+
public static float[] concat(float[]... arrays) {
9475+
int totalLength = 0;
9476+
for (float[] array : arrays) {
9477+
totalLength = addExact(totalLength, array);
9478+
}
9479+
final float[] result = new float[totalLength];
9480+
int currentPos = 0;
9481+
for (float[] array : arrays) {
9482+
if (array != null && array.length > 0) {
9483+
System.arraycopy(array, 0, result, currentPos, array.length);
9484+
currentPos += array.length;
9485+
}
9486+
}
9487+
return result;
9488+
}
9489+
9490+
/**
9491+
* Concatenates multiple int arrays into a single array.
9492+
* <p>
9493+
* This method combines all input arrays in the order they are provided,
9494+
* creating a new array that contains all elements from the input arrays.
9495+
* The resulting array length is the sum of lengths of all non-null input arrays.
9496+
* </p>
9497+
*
9498+
* @param arrays the arrays to concatenate. Can be empty, contain nulls,
9499+
* or be null itself (treated as empty varargs).
9500+
* @return a new int array containing all elements from the input arrays
9501+
* in the order they appear, or an empty array if no elements are present.
9502+
* @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
9503+
* @since 3.21.0
9504+
*/
9505+
public static int[] concat(int[]... arrays) {
9506+
int totalLength = 0;
9507+
for (int[] array : arrays) {
9508+
totalLength = addExact(totalLength, array);
9509+
}
9510+
final int[] result = new int[totalLength];
9511+
int currentPos = 0;
9512+
for (int[] array : arrays) {
9513+
if (array != null && array.length > 0) {
9514+
System.arraycopy(array, 0, result, currentPos, array.length);
9515+
currentPos += array.length;
9516+
}
9517+
}
9518+
return result;
9519+
}
9520+
9521+
/**
9522+
* Concatenates multiple long arrays into a single array.
9523+
* <p>
9524+
* This method combines all input arrays in the order they are provided,
9525+
* creating a new array that contains all elements from the input arrays.
9526+
* The resulting array length is the sum of lengths of all non-null input arrays.
9527+
* </p>
9528+
*
9529+
* @param arrays the arrays to concatenate. Can be empty, contain nulls,
9530+
* or be null itself (treated as empty varargs).
9531+
* @return a new long array containing all elements from the input arrays
9532+
* in the order they appear, or an empty array if no elements are present.
9533+
* @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
9534+
* @since 3.21.0
9535+
*/
9536+
public static long[] concat(long[]... arrays) {
9537+
int totalLength = 0;
9538+
for (long[] array : arrays) {
9539+
totalLength = addExact(totalLength, array);
9540+
}
9541+
final long[] result = new long[totalLength];
9542+
int currentPos = 0;
9543+
for (long[] array : arrays) {
9544+
if (array != null && array.length > 0) {
9545+
System.arraycopy(array, 0, result, currentPos, array.length);
9546+
currentPos += array.length;
9547+
}
9548+
}
9549+
return result;
9550+
}
9551+
9552+
/**
9553+
* Concatenates multiple short arrays into a single array.
9554+
* <p>
9555+
* This method combines all input arrays in the order they are provided,
9556+
* creating a new array that contains all elements from the input arrays.
9557+
* The resulting array length is the sum of lengths of all non-null input arrays.
9558+
* </p>
9559+
*
9560+
* @param arrays the arrays to concatenate. Can be empty, contain nulls,
9561+
* or be null itself (treated as empty varargs).
9562+
* @return a new short array containing all elements from the input arrays
9563+
* in the order they appear, or an empty array if no elements are present.
9564+
* @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
9565+
* @since 3.21.0
9566+
*/
9567+
public static short[] concat(short[]... arrays) {
9568+
int totalLength = 0;
9569+
for (short[] array : arrays) {
9570+
totalLength = addExact(totalLength, array);
9571+
}
9572+
final short[] result = new short[totalLength];
9573+
int currentPos = 0;
9574+
for (short[] array : arrays) {
9575+
if (array != null && array.length > 0) {
9576+
System.arraycopy(array, 0, result, currentPos, array.length);
9577+
currentPos += array.length;
9578+
}
9579+
}
9580+
return result;
9581+
}
9582+
9583+
/**
9584+
* Safely adds the length of an array to a running total, checking for overflow.
9585+
*
9586+
* @param totalLength the current accumulated length
9587+
* @param array the array whose length should be added (can be {@code null},
9588+
* in which case its length is considered 0)
9589+
* @return the new total length after adding the array's length
9590+
* @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
9591+
*/
9592+
private static int addExact(final int totalLength, final Object array) {
9593+
try {
9594+
return MathBridge.addExact(totalLength, getLength(array));
9595+
} catch (final ArithmeticException exception) {
9596+
throw new IllegalArgumentException("Total arrays length exceed " + SAFE_MAX_ARRAY_LENGTH);
9597+
}
9598+
}
9599+
93359600
/**
93369601
* ArrayUtils instances should NOT be constructed in standard programming. Instead, the class should be used as {@code ArrayUtils.clone(new int[] {2})}.
93379602
* <p>
@@ -9344,4 +9609,13 @@ public static String[] toStringArray(final Object[] array, final String valueFor
93449609
public ArrayUtils() {
93459610
// empty
93469611
}
9612+
9613+
/**
9614+
* Bridge class to {@link Math} methods for testing purposes.
9615+
*/
9616+
static class MathBridge {
9617+
static int addExact(final int a, final int b) {
9618+
return Math.addExact(a, b);
9619+
}
9620+
}
93479621
}

0 commit comments

Comments
 (0)