Pregunta ¿Cómo puedo concatenar dos matrices en Java?


Necesito concatenar dos matrices de cadenas en Java.

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

¿Cuál es la forma más fácil de hacer esto?


1134


origen


Respuestas:


Encontré una solución de una línea de la buena y antigua biblioteca Apache Commons Lang.
  ArrayUtils.addAll(T[], T...)

Código:

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

922



Aquí hay un método simple que concatenará dos matrices y devolverá el resultado:

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

Tenga en cuenta que no funcionará con primitivas, solo con tipos de objetos.

La siguiente versión ligeramente más complicada funciona tanto con matrices primitivas como con objetos. Lo hace mediante el uso de T en lugar de T[] como el tipo de argumento.

También hace posible concatenar matrices de dos tipos diferentes seleccionando el tipo más general como el tipo de componente del resultado.

public static <T> T concatenate(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;
}

Aquí hay un ejemplo:

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

721



Es posible escribir una versión completamente genérica que incluso se puede extender para concatenar cualquier cantidad de matrices. Estas versiones requieren Java 6, ya que usan Arrays.copyOf()

Ambas versiones evitan crear intermediarios List objetos y uso System.arraycopy() para garantizar que la copia de grandes arreglos sea lo más rápida posible.

Para dos matrices, se ve así:

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

Y para un número arbitrario de matrices (> = 1) se ve así:

public static <T> T[] concatAll(T[] first, T[]... rest) {
  int totalLength = first.length;
  for (T[] array : rest) {
    totalLength += array.length;
  }
  T[] result = Arrays.copyOf(first, totalLength);
  int offset = first.length;
  for (T[] array : rest) {
    System.arraycopy(array, 0, result, offset, array.length);
    offset += array.length;
  }
  return result;
}

440



One-liner en Java 8:

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

O:

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

326



O con el amado Guayaba:

String[] both = ObjectArrays.concat(first, second, String.class);

Además, hay versiones para matrices primitivas:

  • Booleans.concat(first, second)
  • Bytes.concat(first, second)
  • Chars.concat(first, second)
  • Doubles.concat(first, second)
  • Shorts.concat(first, second)
  • Ints.concat(first, second)
  • Longs.concat(first, second)
  • Floats.concat(first, second)

168



Usando la API de Java:

String[] f(String[] first, String[] second) {
    List<String> both = new ArrayList<String>(first.length + second.length);
    Collections.addAll(both, first);
    Collections.addAll(both, second);
    return both.toArray(new String[both.size()]);
}

53



Una solución 100% viejo java y sin  System.arraycopy (no disponible en el cliente GWT, por ejemplo):

static String[] concat(String[]... arrays) {
    int length = 0;
    for (String[] array : arrays) {
        length += array.length;
    }
    String[] result = new String[length];
    int pos = 0;
    for (String[] array : arrays) {
        for (String element : array) {
            result[pos] = element;
            pos++;
        }
    }
    return result;
}

36



Recientemente luché contra problemas con la rotación excesiva de memoria. Si se sabe que a y / o b están comúnmente vacíos, aquí hay otra adaptación del código de silvertab (también generizado):

private static <T> T[] concat(T[] a, T[] b) {
    final int alen = a.length;
    final int blen = b.length;
    if (alen == 0) {
        return b;
    }
    if (blen == 0) {
        return a;
    }
    final T[] result = (T[]) java.lang.reflect.Array.
            newInstance(a.getClass().getComponentType(), alen + blen);
    System.arraycopy(a, 0, result, 0, alen);
    System.arraycopy(b, 0, result, alen, blen);
    return result;
}

(En cualquier caso, ¡el comportamiento de reutilización de la matriz debe ser claramente JavaDoced!)


29



los Java funcional library tiene una clase de contenedor de matriz que equipa matrices con métodos prácticos como la concatenación.

import static fj.data.Array.array;

...y entonces

Array<String> both = array(first).append(array(second));

Para volver a sacar la matriz desenvuelta, llame

String[] s = both.array();

26



ArrayList<String> both = new ArrayList(Arrays.asList(first));
both.addAll(Arrays.asList(second));

both.toArray(new String[0]);

22