我需要在Java中连接两个字符串数组。

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

哪种方法最简单?


当前回答

我发现我必须处理数组可以为空的情况。。。

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

其他回答

算法爱好者的另一个答案是:

public static String[] mergeArrays(String[] array1, String[] array2) {
    int totalSize = array1.length + array2.length; // Get total size
    String[] merged = new String[totalSize]; // Create new array
    // Loop over the total size
    for (int i = 0; i < totalSize; i++) {
        if (i < array1.length) // If the current position is less than the length of the first array, take value from first array
            merged[i] = array1[i]; // Position in first array is the current position

        else // If current position is equal or greater than the first array, take value from second array.
            merged[i] = array2[i - array1.length]; // Position in second array is current position minus length of first array.
    }

    return merged;

用法:

String[] array1str = new String[]{"a", "b", "c", "d"}; 
String[] array2str = new String[]{"e", "f", "g", "h", "i"};
String[] listTotalstr = mergeArrays(array1str, array2str);
System.out.println(Arrays.toString(listTotalstr));

结果:

[a, b, c, d, e, f, g, h, i]

下面是一个简单的方法,它将连接两个数组并返回结果:

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

请注意,它不适用于基本数据类型,仅适用于对象类型。

以下稍微复杂一点的版本同时适用于对象数组和基元数组。它通过使用T而不是T[]作为参数类型来实现这一点。

它还可以通过选择最通用的类型作为结果的组件类型来连接两种不同类型的数组。

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

下面是一个示例:

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 }));
public int[] mergeArrays(int [] a, int [] b) {
    int [] merged = new int[a.length + b.length];
    int i = 0, k = 0, l = a.length;
    int j = a.length > b.length ? a.length : b.length;
    while(i < j) {
        if(k < a.length) {
            merged[k] = a[k];
            k++;
        }
        if((l - a.length) < b.length) {
            merged[l] = b[l - a.length];
            l++;
        }
        i++;
    }
    return merged;
}

每个答案都是复制数据并创建新阵列。这并不是绝对必要的,如果您的阵列相当大,这绝对不是您想要做的。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
}

这里是silvertab解决方案的一个修改,对泛型进行了改进:

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

注意:请参阅Joachim的Java 6解决方案答案。它不仅消除了警告;它也更短,更高效,更容易阅读!