This article is participating in “Java Theme Month – Java Debug Notes Event”, see < Event link > for more details.

The problem

In Java, I want to concatenate two arrays of strings.

void f(String[] first, String[] second) {
    String[] both = ???
}
Copy the code

What’s the easiest way to do that?

answer

Answer 1

Use a line from the Apache Commons Lang library arrayutils.addall (T[], T…) You can do that.

String[] both = ArrayUtils.addAll(first, second);
Copy the code

Answer 2

Here’s a simple way to concatenate two arrays and return the result:

public <T> T[] concatenate(T[] a, T[] b) {
    int aLen = a.length;
    int bLen = b.length;

    @SuppressWarnings("unchecked")
    T[] c = (T[]) Array.newInstance(a.getClass().getComponentType(), aLen + bLen);
    System.arraycopy(a, 0, c, 0, aLen);
    System.arraycopy(b, 0, c, aLen, bLen);

    return c;
}
Copy the code

Note: The above method does not apply to primitive data types, only object types.

The slightly more complex method below applies to both object arrays and primitive arrays and is implemented using T instead of T[] as the argument type.

Use generics to concatenate two arrays of strings of different types and return the result as a generic type.

public static <T> T concatenate(T a, T b) {
    if(! a.getClass().isArray() || ! b.getClass().isArray()) {throw newIllegalArgumentException(); } Class<? > resCompType; Class<? > aCompType = a.getClass().getComponentType(); Class<? > bCompType = b.getClass().getComponentType();if (aCompType.isAssignableFrom(bCompType)) {
        resCompType = aCompType;
    } else if (bCompType.isAssignableFrom(aCompType)) {
        resCompType = bCompType;
    } else {
        throw new IllegalArgumentException();
    }

    int aLen = Array.getLength(a);
    int bLen = Array.getLength(b);

    @SuppressWarnings("unchecked")
    T result = (T) Array.newInstance(resCompType, aLen + bLen);
    System.arraycopy(a, 0, result, 0, aLen);
    System.arraycopy(b, 0, result, aLen, bLen);        

    return result;
}
Copy the code

Such as:

Assert.assertArrayEquals(new int[] { 1.2.3 }, concatenate(new int[] { 1.2 }, new int[] { 3 }));
Assert.assertArrayEquals(new Number[] { 1.2.3f }, concatenate(new Integer[] { 1.2 }, new Number[] { 3f }));
Copy the code

Answer 3

Using Stream in Java 8:

String[] both = Stream.concat(Arrays.stream(a), Arrays.stream(b))
                      .toArray(String[]::new);
Copy the code

Or, use flagMap:

String[] both = Stream.of(a, b).flatMap(Stream::of)
                      .toArray(String[]::new);
Copy the code

For generics, you can also use reflection:

@SuppressWarnings("unchecked")
T[] both = Stream.concat(Arrays.stream(a), Arrays.stream(b)).toArray(
    size -> (T[]) Array.newInstance(a.getClass().getComponentType(), size));
Copy the code

Translation content sources Stack Overflow:stackoverflow.com/questions/8…