在Java中如何连接两个数组?

1577

我需要在Java中合并两个String数组。

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

最简单的方法是什么?


4
Guava 中的 Bytes.concat 函数 - Ben Page
2
我看到这里有很多回复,但问题用词不当(“最简单的方法”?)无法表明最佳答案... - Artur Opalinski
3
这里有数十个答案将数据复制到一个新数组中,因为这是要求的 - 但是当不是严格必要时复制数据是一件坏事,特别是在Java中。相反,跟踪索引并将这两个数组视为已连接即可。我添加了一个说明这种技术的解决方案。 - Douglas Held
47
这个问题目前有50个不同的答案,让我想知道为什么Java从未提供一个简单的array1 + array2连接函数。 - JollyJoker
2
你可以用两行标准的Java代码完美高效地实现它(请参见我的答案),因此使用单个方法并不能获得太多好处。所有这些奇怪而神奇的解决方案都有点浪费时间。 - rghome
显示剩余2条评论
66个回答

2
如果您希望在解决方案中使用 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()]);
}

2
我认为使用泛型的最佳解决方案是:
/* 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 
 * https://dev59.com/onE85IYBdhLWcg3wikO-
 * 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;
}

这段代码看起来很有用,可以捕获对象和基本类型。然而,我不会将一个函数称为 resizeArray,因为在Java中数组是不能被调整大小的。这就是为什么 Arrays.copyOf 做同样的事情,但使用了不同的方法名称。 - Maarten Bodewes
不是这样的,copyOf 只是在长度相同的情况下制作副本。如果您仔细阅读代码,就会意识到该函数接收参数 newSize,因此 resizeArray 就是返回调整大小后的数组。 - spacebiker

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

这非常复杂,难以理解,没有文档说明,并且循环中有两个if语句,效率也不高。 - Maarten Bodewes

1
非Java 8解决方案:
public static int[] combineArrays(int[] a, int[] b) {
        int[] c = new int[a.length + b.length];

        for (int i = 0; i < a.length; i++) {
            c[i] = a[i];
        }

        for (int j = 0, k = a.length; j < b.length; j++, k++) {
            c[k] = b[j];
        }

        return c;
    }

1
 /**
     * With Java Streams
     * @param first First Array
     * @param second Second Array
     * @return Merged Array
     */
    String[] mergeArrayOfStrings(String[] first, String[] second) {
        return Stream.concat(Arrays.stream(first), Arrays.stream(second)).toArray(String[]::new);
    }

0
Object[] obj = {"hi","there"};
Object[] obj2 ={"im","fine","what abt u"};
Object[] obj3 = new Object[obj.length+obj2.length];

for(int i =0;i<obj3.length;i++)
    obj3[i] = (i<obj.length)?obj[i]:obj2[i-obj.length];

0

在Java 8中

public String[] concat(String[] arr1, String[] arr2){
    Stream<String> stream1 = Stream.of(arr1);
    Stream<String> stream2 = Stream.of(arr2);
    Stream<String> stream = Stream.concat(stream1, stream2);
    return Arrays.toString(stream.toArray(String[]::new));
}

这与之前的答案相同,即2016年2月10日。 - rghome
@rghome 你可以通过点击分享按钮来链接到答案。基本上,如果有一个早期的重复问题,为什么不删除答案呢?如果有遗漏的地方,你也可以改进现有的答案。 - Maarten Bodewes

0
你可以尝试使用连接多个数组的方法:
public static <T> T[] concatMultipleArrays(T[]... arrays)
{
   int length = 0;
   for (T[] array : arrays)
   {
      length += array.length;
   }
   T[] result = (T[]) Array.newInstance(arrays.getClass().getComponentType(), length) ;

   length = 0;
   for (int i = 0; i < arrays.length; i++)
   {
      System.arraycopy(arrays[i], 0, result, length, arrays[i].length);
      length += arrays[i].length;
   }

   return result;
}

0
Object[] mixArray(String[] a, String[] b)
String[] s1 = a;
String[] s2 = b;
Object[] result;
List<String> input = new ArrayList<String>();
for (int i = 0; i < s1.length; i++)
{
    input.add(s1[i]);
}
for (int i = 0; i < s2.length; i++)
{
    input.add(s2[i]);
}
result = input.toArray();
return result;

0
我有一个简单的方法。你不需要浪费时间去研究复杂的Java函数或库。但返回类型应该是字符串。
String[] f(String[] first, String[] second) {

    // Variable declaration part
    int len1 = first.length;
    int len2 = second.length;
    int lenNew = len1 + len2;
    String[] both = new String[len1+len2];

    // For loop to fill the array "both"
    for (int i=0 ; i<lenNew ; i++){
        if (i<len1) {
            both[i] = first[i];
        } else {
            both[i] = second[i-len1];
        }
    }

    return both;

}

如此简单...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接