Как я могу объединить два массива в Java? - PullRequest
1243 голосов
/ 17 сентября 2008

Мне нужно объединить два String массива в Java.

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

Какой самый простой способ сделать это?

Ответы [ 58 ]

3 голосов
/ 24 апреля 2009

Простой, но неэффективный способ сделать это (дженерики не включены):

ArrayList baseArray = new ArrayList(Arrays.asList(array1));
baseArray.addAll(Arrays.asList(array2));
String concatenated[] = (String []) baseArray.toArray(new String[baseArray.size()]);
3 голосов
/ 29 декабря 2010
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;
}
3 голосов
/ 21 июня 2013
String [] both = new ArrayList<String>(){{addAll(Arrays.asList(first)); addAll(Arrays.asList(second));}}.toArray(new String[0]);
2 голосов
/ 30 июля 2014

Я думаю, что лучшее решение с использованием дженериков будет:

/* This for non primitive types */
public static <T> T[] concatenate (T[]... elements) {

    T[] C = null;
    for (T[] element: elements) {
        if (element==null) continue;
        if (C==null) C = (T[]) Array.newInstance(element.getClass().getComponentType(), element.length);
        else C = resizeArray(C, C.length+element.length);

        System.arraycopy(element, 0, C, C.length-element.length, element.length);
    }

    return C;
}

/**
 * as far as i know, primitive types do not accept generics 
 * http://stackoverflow.com/questions/2721546/why-dont-java-generics-support-primitive-types
 * for primitive types we could do something like this:
 * */
public static int[] concatenate (int[]... elements){
    int[] C = null;
    for (int[] element: elements) {
        if (element==null) continue;
        if (C==null) C = new int[element.length];
        else C = resizeArray(C, C.length+element.length);

        System.arraycopy(element, 0, C, C.length-element.length, element.length);
    }
    return C;
}

private static <T> T resizeArray (T array, int newSize) {
    int oldSize =
            java.lang.reflect.Array.getLength(array);
    Class elementType =
            array.getClass().getComponentType();
    Object newArray =
            java.lang.reflect.Array.newInstance(
                    elementType, newSize);
    int preserveLength = Math.min(oldSize, newSize);
    if (preserveLength > 0)
        System.arraycopy(array, 0,
                newArray, 0, preserveLength);
    return (T) newArray;
}
2 голосов
/ 05 сентября 2016

Каждый ответ копирует данные и создает новый массив. Это не является строго необходимым и определенно НЕ то, что вы хотите делать, если ваши массивы достаточно велики. Создатели Java уже знали, что копии массивов расточительны, и именно поэтому они предоставили нам System.arrayCopy () для выполнения тех операций вне Java, когда это необходимо.

Вместо того, чтобы копировать ваши данные, рассмотрите возможность оставить их на месте и взять их там, где они лежат. Копирование местоположений данных только потому, что программист хотел бы организовать их, не всегда целесообразно.

// I have arrayA and arrayB; would like to treat them as concatenated
// but leave my damn bytes where they are!
Object accessElement ( int index ) {
     if ( index < 0 ) throw new ArrayIndexOutOfBoundsException(...);
     // is reading from the head part?
     if ( index < arrayA.length )
          return arrayA[ index ];
     // is reading from the tail part?
     if ( index < ( arrayA.length + arrayB.length ) )
          return arrayB[ index - arrayA.length ];
     throw new ArrayIndexOutOfBoundsException(...); // index too large
}
2 голосов
/ 29 ноября 2016

Вот код AbacusUtil .

String[] a = {"a", "b", "c"};
String[] b = {"1", "2", "3"};
String[] c = N.concat(a, b); // c = ["a", "b", "c", "1", "2", "3"]

// N.concat(...) is null-safety.
a = null;
c = N.concat(a, b); // c = ["1", "2", "3"]
2 голосов
/ 14 июля 2011
Import java.util.*;

String array1[] = {"bla","bla"};
String array2[] = {"bla","bla"};

ArrayList<String> tempArray = new ArrayList<String>(Arrays.asList(array1));
tempArray.addAll(Arrays.asList(array2));
String array3[] = films.toArray(new String[1]); // size will be overwritten if needed

Вы можете заменить String типом / классом по своему вкусу

Я уверен, что это можно сделать короче и лучше, но это работает, и мне лень разбираться с этим дальше ...

2 голосов
/ 30 апреля 2012

Я обнаружил, что имел дело со случаем, когда массивы могут быть нулевыми ...

private double[] concat  (double[]a,double[]b){
    if (a == null) return b;
    if (b == null) return a;
    double[] r = new double[a.length+b.length];
    System.arraycopy(a, 0, r, 0, a.length);
    System.arraycopy(b, 0, r, a.length, b.length);
    return r;

}
private double[] copyRest (double[]a, int start){
    if (a == null) return null;
    if (start > a.length)return null;
    double[]r = new double[a.length-start];
    System.arraycopy(a,start,r,0,a.length-start); 
    return r;
}
2 голосов
/ 26 февраля 2016
public static String[] toArray(String[]... object){
    List<String> list=new ArrayList<>();
    for (String[] i : object) {
        list.addAll(Arrays.asList(i));
    }
    return list.toArray(new String[list.size()]);
}
2 голосов
/ 25 сентября 2008

Если вы хотите работать с ArrayLists в решении, вы можете попробовать это:

public final String [] f(final String [] first, final String [] second) {
    // Assuming non-null for brevity.
    final ArrayList<String> resultList = new ArrayList<String>(Arrays.asList(first));
    resultList.addAll(new ArrayList<String>(Arrays.asList(second)));
    return resultList.toArray(new String [resultList.size()]);
}
...