В этой статье мы рассмотрим несколько способов объединения двух массивов. В зависимости от типа элементов (ссылочный или примитивный тип) массива и требований к быстродействию можно применить разные по краткости и удобочитаемости способы.

Объединения двух массивов с элементами ссылочного типа

Данным способом можно объединить массивы ссылочного типа (то есть не массивы с примитивами). Данный способ работает в Java 6 и выше.

public static <T> T[] concat(T[] first, T[] second) {
    T[] result = Arrays.copyOf(first, first.length + second.length);
    System.arraycopy(second, 0, result, first.length, second.length);
    return result;
}

Можно воспользоваться возможностями Java 8 и сделать объединение массивов с помощью стримов:

@SuppressWarnings("unchecked")
public static <T> T[] concatUsingStream(T[] a, T[] b) {
    return Stream.concat(Arrays.stream(a), Arrays.stream(b)).toArray(
            size -> (T[]) Array.newInstance(a.getClass().getComponentType(), size));
}

Объединения двух массивов с элементами любого типа

В отличие от предыдущего способа, здесь мы можем объединить массивы не только ссылочного типа, но и примитивного:

public static <T> T concatAny(T a, T b) {
    if (!a.getClass().isArray() || !b.getClass().isArray()) {
        throw new IllegalArgumentException();
    }

    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;
}

Объединение массивов с помощью ArrayUtils

Наиболее лаконичный способ объединить элементы двух массивов – это воспользоваться классов ArrayUtils из Commons Lang. Для этого сначала нужно подключить библиотеку в проект:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.9</version>
</dependency>
String[] a = new String[]{"A", "B", "C"};
String[] b = new String[]{"D", "E", "F"};

ArrayUtils.addAll(a, b); // [A, B, C, D, E, F]

Исходный код

import org.apache.commons.lang3.ArrayUtils;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.stream.Stream;

public class UnionArraysExample {

    public static void main(String[] args) {
        String[] a = new String[]{"A", "B", "C"};
        String[] b = new String[]{"D", "E", "F"};

        int[] c = new int[]{1, 2, 3};
        int[] d = new int[]{4, 5, 6};

        System.out.println(Arrays.toString(concat(a, b)));

        System.out.println(Arrays.toString(concatAny(c, d)));

        System.out.println(Arrays.toString(concatUsingStream(a, b)));

        System.out.println(Arrays.toString(ArrayUtils.addAll(a, b))); // [A, B, C, D, E, F]
    }

    public static <T> T[] concat(T[] first, T[] second) {
        T[] result = Arrays.copyOf(first, first.length + second.length);
        System.arraycopy(second, 0, result, first.length, second.length);
        return result;
    }

    public static <T> T concatAny(T a, T b) {
        if (!a.getClass().isArray() || !b.getClass().isArray()) {
            throw new IllegalArgumentException();
        }

        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;
    }

    @SuppressWarnings("unchecked")
    public static <T> T[] concatUsingStream(T[] a, T[] b) {
        return Stream.concat(Arrays.stream(a), Arrays.stream(b)).toArray(
                size -> (T[]) Array.newInstance(a.getClass().getComponentType(), size));
    }
}

Заключение

В этой статье мы рассмотрели различные способы для объединения двух массивов.

Как объединить два массива