vectores unir tipos intercalar guardar datos concatenar como arreglos arreglo java arrays concatenation add

tipos - unir dos arraylist java



¿Cómo puedo concatenar dos arreglos en Java? (30)

¡Guauu! Muchas respuestas complejas incluyen algunas simples que dependen de dependencias externas. ¿Qué tal si lo hacemos así?

String [] arg1 = new String{"a","b","c"}; String [] arg2 = new String{"x","y","z"}; ArrayList<String> temp = new ArrayList<String>(); temp.addAll(Arrays.asList(arg1)); temp.addAll(Arrays.asList(arg2)); String [] concatedArgs = temp.toArray(new String[arg1.length+arg2.length]);

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?


Aquí está mi versión ligeramente mejorada de concatAll de Joachim Sauer. Puede funcionar en Java 5 o 6, utilizando System.arraycopy de Java 6 si está disponible en tiempo de ejecución. Este método (IMHO) es perfecto para Android, ya que funciona en Android <9 (que no tiene System.arraycopy) pero utilizará el método más rápido si es posible.

public static <T> T[] concatAll(T[] first, T[]... rest) { int totalLength = first.length; for (T[] array : rest) { totalLength += array.length; } T[] result; try { Method arraysCopyOf = Arrays.class.getMethod("copyOf", Object[].class, int.class); result = (T[]) arraysCopyOf.invoke(null, first, totalLength); } catch (Exception e){ //Java 6 / Android >= 9 way didn''t work, so use the "traditional" approach result = (T[]) java.lang.reflect.Array.newInstance(first.getClass().getComponentType(), totalLength); System.arraycopy(first, 0, result, 0, first.length); } int offset = first.length; for (T[] array : rest) { System.arraycopy(array, 0, result, offset, array.length); offset += array.length; } return result; }


Aquí hay un método simple que concatena dos matrices y devuelve 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 primitivos, solo con tipos de objetos.

La siguiente versión, ligeramente más complicada, funciona con matrices de objetos y primitivas. Lo hace usando T lugar de T[] como tipo de argumento.

También permite 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 }));


Aquí hay una adaptación de la solución de silvertab, con genéricos modificados:

static <T> T[] concat(T[] a, T[] b) { final int alen = a.length; final int blen = b.length; 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; }

NOTA: Vea la respuesta de Joachim para una solución Java 6. No solo elimina la advertencia; ¡También es más corto, más eficiente y más fácil de leer!


Aquí una posible implementación en código de trabajo de la solución de pseudo código escrita por silvertab.

Gracias silvertab!

public class Array { public static <T> T[] concat(T[] a, T[] b, ArrayBuilderI<T> builder) { T[] c = builder.build(a.length + b.length); System.arraycopy(a, 0, c, 0, a.length); System.arraycopy(b, 0, c, a.length, b.length); return c; } }

Siguiente siguiente es la interfaz del constructor.

Nota: es necesario un constructor porque en java no es posible hacer

new T[size]

Debido al borrado de tipo genérico:

public interface ArrayBuilderI<T> { public T[] build(int size); }

Aquí un constructor concreto implementando la interfaz, construyendo una matriz Integer :

public class IntegerArrayBuilder implements ArrayBuilderI<Integer> { @Override public Integer[] build(int size) { return new Integer[size]; } }

Y finalmente la aplicación / prueba:

@Test public class ArrayTest { public void array_concatenation() { Integer a[] = new Integer[]{0,1}; Integer b[] = new Integer[]{2,3}; Integer c[] = Array.concat(a, b, new IntegerArrayBuilder()); assertEquals(4, c.length); assertEquals(0, (int)c[0]); assertEquals(1, (int)c[1]); assertEquals(2, (int)c[2]); assertEquals(3, (int)c[3]); } }


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

Código:

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


Es posible escribir una versión totalmente genérica que incluso se puede ampliar para concatenar cualquier número de arreglos. Estas versiones requieren Java 6, ya que usan Arrays.copyOf()

Ambas versiones evitan la creación de objetos de List intermediarios y utilizan System.arraycopy() para garantizar que copiar arreglos grandes sea lo más rápido 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; }


Esta es una función convertida para un array String:

public String[] mergeArrays(String[] mainArray, String[] addArray) { String[] finalArray = new String[mainArray.length + addArray.length]; System.arraycopy(mainArray, 0, finalArray, 0, mainArray.length); System.arraycopy(addArray, 0, finalArray, mainArray.length, addArray.length); return finalArray; }


Esto funciona, pero necesita insertar su propia comprobación de errores.

public class StringConcatenate { public static void main(String[] args){ // Create two arrays to concatenate and one array to hold both String[] arr1 = new String[]{"s","t","r","i","n","g"}; String[] arr2 = new String[]{"s","t","r","i","n","g"}; String[] arrBoth = new String[arr1.length+arr2.length]; // Copy elements from first array into first part of new array for(int i = 0; i < arr1.length; i++){ arrBoth[i] = arr1[i]; } // Copy elements from second array into last part of new array for(int j = arr1.length;j < arrBoth.length;j++){ arrBoth[j] = arr2[j-arr1.length]; } // Print result for(int k = 0; k < arrBoth.length; k++){ System.out.print(arrBoth[k]); } // Additional line to make your terminal look better at completion! System.out.println(); } }

Probablemente no sea el más eficiente, pero no se basa en otra cosa que no sea la API de Java.


La biblioteca funcional de Java tiene una clase de envoltura de matriz que equipa matrices con métodos prácticos como concatenación.

import static fj.data.Array.array;

...y entonces

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

Para volver a sacar la matriz sin envolver, llame al

String[] s = both.array();


O con la amada Guava :

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)

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


Otra forma con Java8 usando Stream

public String[] concatString(String[] a, String[] b){ Stream<String> streamA = Arrays.stream(a); Stream<String> streamB = Arrays.stream(b); return Stream.concat(streamA, streamB).toArray(String[]::new); }


Otra forma de pensar sobre la pregunta. Para concatenar dos o más matrices, hay que hacer una lista de todos los elementos de cada una y luego construir una nueva matriz. Esto suena como crear una List<T> y luego llama a toArray en ella. Algunas otras respuestas usan ArrayList , y eso está bien. Pero ¿qué tal si implementamos el nuestro? No es dificil:

private static <T> T[] addAll(final T[] f, final T...o){ return new AbstractList<T>(){ @Override public T get(int i) { return i>=f.length ? o[i - f.length] : f[i]; } @Override public int size() { return f.length + o.length; } }.toArray(f); }

Creo que lo anterior es equivalente a las soluciones que utilizan System.arraycopy . Sin embargo creo que esta tiene su propia belleza.


Por favor, perdóneme por agregar otra versión a esta lista ya larga. Miré cada respuesta y decidí que realmente quería una versión con un solo parámetro en la firma. También agregué algunas comprobaciones de argumentos para beneficiarme de una falla temprana con información sensible en caso de una entrada inesperada.

@SuppressWarnings("unchecked") public static <T> T[] concat(T[]... inputArrays) { if(inputArrays.length < 2) { throw new IllegalArgumentException("inputArrays must contain at least 2 arrays"); } for(int i = 0; i < inputArrays.length; i++) { if(inputArrays[i] == null) { throw new IllegalArgumentException("inputArrays[" + i + "] is null"); } } int totalLength = 0; for(T[] array : inputArrays) { totalLength += array.length; } T[] result = (T[]) Array.newInstance(inputArrays[0].getClass().getComponentType(), totalLength); int offset = 0; for(T[] array : inputArrays) { System.arraycopy(array, 0, result, offset, array.length); offset += array.length; } return result; }


Puede agregar las dos matrices en dos líneas de código.

String[] both = Arrays.copyOf(first, first.length + second.length); System.arraycopy(second, 0, both, first.length, second.length);

Esta es una solución rápida y eficiente y funcionará para los tipos primitivos, así como los dos métodos involucrados están sobrecargados.

Debe evitar las soluciones que involucren ArrayLists, secuencias, etc., ya que éstas deberán asignar memoria temporal sin ningún propósito útil.

Debes evitar los bucles ya que estos no son eficientes. Los métodos incorporados utilizan funciones de copia en bloque que son extremadamente rápidas.


Puede intentar convertirlo en un Arraylist y usar el método addAll y luego volver a convertirlo en una matriz.

List list = new ArrayList(Arrays.asList(first)); list.addAll(Arrays.asList(second)); String[] both = list.toArray();


Qué tal si :

public String[] combineArray (String[] ... strings) { List<String> tmpList = new ArrayList<String>(); for (int i = 0; i < strings.length; i++) tmpList.addAll(Arrays.asList(strings[i])); return tmpList.toArray(new String[tmpList.size()]); }


Que tal simplemente

public static class Array { public static <T> T[] concat(T[]... arrays) { ArrayList<T> al = new ArrayList<T>(); for (T[] one : arrays) Collections.addAll(al, one); return (T[]) al.toArray(arrays[0].clone()); } }

Y solo haz Array.concat(arr1, arr2) . Siempre que arr1 y arr2 sean del mismo tipo, esto le dará otra matriz del mismo tipo que contiene ambas matrices.


Recientemente he luchado 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 (generado también):

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!)


Si utiliza esta forma, no necesita importar ninguna clase de terceros.

Si quieres concatenar String

Código de ejemplo para concate dos String Array

public static String[] combineString(String[] first, String[] second){ int length = first.length + second.length; String[] result = new String[length]; System.arraycopy(first, 0, result, 0, first.length); System.arraycopy(second, 0, result, first.length, second.length); return result; }

Si quieres concatenar Int

Código de ejemplo para concate dos Integer Array

public static int[] combineInt(int[] a, int[] b){ int length = a.length + b.length; int[] result = new int[length]; System.arraycopy(a, 0, result, 0, a.length); System.arraycopy(b, 0, result, a.length, b.length); return result; }

Aquí está el método principal

public static void main(String[] args) { String [] first = {"a", "b", "c"}; String [] second = {"d", "e"}; String [] joined = combineString(first, second); System.out.println("concatenated String array : " + Arrays.toString(joined)); int[] array1 = {101,102,103,104}; int[] array2 = {105,106,107,108}; int[] concatenateInt = combineInt(array1, array2); System.out.println("concatenated Int array : " + Arrays.toString(concatenateInt)); } }

Podemos usar de esta manera también.


Una forma fácil, pero ineficiente de hacer esto (genéricos no incluidos):

ArrayList baseArray = new ArrayList(Arrays.asList(array1)); baseArray.addAll(Arrays.asList(array2)); String concatenated[] = (String []) baseArray.toArray(new String[baseArray.size()]);


Una solución 100% antigua 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; }


Una variación independiente del tipo (ACTUALIZADA - gracias a Volley por crear una instancia de T):

@SuppressWarnings("unchecked") public static <T> T[] join(T[]...arrays) { final List<T> output = new ArrayList<T>(); for(T[] array : arrays) { output.addAll(Arrays.asList(array)); } return output.toArray((T[])Array.newInstance( arrays[0].getClass().getComponentType(), output.size())); }


Una variación simple que permite la unión de más de una matriz:

public static String[] join(String[]...arrays) { final List<String> output = new ArrayList<String>(); for(String[] array : arrays) { output.addAll(Arrays.asList(array)); } return output.toArray(new String[output.size()]); }


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


Usando solo la API de Javas:

String[] join(String[]... arrays) { // calculate size of target array int size = 0; for (String[] array : arrays) { size += array.length; } // create list of appropriate size java.util.List list = new java.util.ArrayList(size); // add arrays for (String[] array : arrays) { list.addAll(java.util.Arrays.asList(array)); } // create and return final array return list.toArray(new String[size]); }

Ahora, este código no es el más eficiente, pero solo se basa en clases Java estándar y es fácil de entender. Funciona para cualquier número de String [] (incluso cero arreglos).


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


String [] both = new ArrayList<String>(){{addAll(Arrays.asList(first)); addAll(Arrays.asList(second));}}.toArray(new String[0]);


public String[] concat(String[]... arrays) { int length = 0; for (String[] array : arrays) { length += array.length; } String[] result = new String[length]; int destPos = 0; for (String[] array : arrays) { System.arraycopy(array, 0, result, destPos, array.length); destPos += array.length; } return result; }