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

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

哪种方法最简单?


当前回答

您可以在两行代码中追加这两个数组。

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

这是一个快速有效的解决方案,适用于原始类型以及所涉及的两个方法都是重载的。

您应该避免使用涉及ArrayList、流等的解决方案,因为这些解决方案需要分配临时内存,没有任何用处。

对于大型数组,应避免for循环,因为这些循环效率不高。内置方法使用速度极快的块复制函数。

其他回答

在Java 8中使用流:

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

或者像这样,使用flatMap:

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

要对泛型类型执行此操作,必须使用反射:

@SuppressWarnings("unchecked")
T[] both = Stream.concat(Arrays.stream(a), Arrays.stream(b)).toArray(
    size -> (T[]) Array.newInstance(a.getClass().getComponentType(), size));
ArrayList<String> both = new ArrayList(Arrays.asList(first));
both.addAll(Arrays.asList(second));

both.toArray(new String[0]);

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

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 String[] concat(String[] firstArr,String[] secondArr){
        //if both is empty just return
        if(firstArr.length==0 && secondArr.length==0)return new String[0];

        String[] res = new String[firstArr.length+secondArr.length];
        int idxFromFirst=0;

        //loop over firstArr, idxFromFirst will be used as starting offset for secondArr
        for(int i=0;i<firstArr.length;i++){
            res[i] = firstArr[i];
            idxFromFirst++;
        }

        //loop over secondArr, with starting offset idxFromFirst (the offset track from first array)
        for(int i=0;i<secondArr.length;i++){
            res[idxFromFirst+i]=secondArr[i];
        }

        return res;
    }

就这样,对吧?他没有说他关心订单或任何事情。这应该是最简单的方法。

看看这个优雅的解决方案(如果您需要除char以外的其他类型,请更改它):

private static void concatArrays(char[] destination, char[]... sources) {
    int currPos = 0;
    for (char[] source : sources) {
        int length = source.length;
        System.arraycopy(source, 0, destination, currPos, length);
        currPos += length;
    }
}

您可以连接每个数组计数。