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

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

哪种方法最简单?


当前回答

您可以尝试连接多个数组的方法:

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

其他回答

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

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

应该会成功的。这是假设String[]第一个,String[]第二个

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

使用Java 8+流,您可以编写以下函数:

private static String[] concatArrays(final String[]... arrays) {
    return Arrays.stream(arrays)
         .flatMap(Arrays::stream)
         .toArray(String[]::new);
}

我认为泛型的最佳解决方案是:

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