在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个回答

0

只是想补充一下,你也可以使用 System.arraycopy

import static java.lang.System.out;
import static java.lang.System.arraycopy;
import java.lang.reflect.Array;
class Playground {
    @SuppressWarnings("unchecked")
    public static <T>T[] combineArrays(T[] a1, T[] a2) {
        T[] result = (T[]) Array.newInstance(a1.getClass().getComponentType(), a1.length+a2.length);
        arraycopy(a1,0,result,0,a1.length);
        arraycopy(a2,0,result,a1.length,a2.length);
        return result;
    }
    public static void main(String[ ] args) {
        String monthsString = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
        String[] months = monthsString.split("(?<=\\G.{3})");
        String daysString = "SUNMONTUEWEDTHUFRISAT";
        String[] days = daysString.split("(?<=\\G.{3})");
        for (String m : months) {
            out.println(m);
        }
        out.println("===");
         for (String d : days) {
            out.println(d);
        }
        out.println("===");
        String[] results = combineArrays(months, days);
        for (String r : results) {
            out.println(r);
        }
        out.println("===");
    }
}

-1

看看这个优雅的解决方案(如果你需要其他类型而不是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;
    }
}

您可以连接任意数量的数组。


欢迎来到stackoverflow。由于这个问题已经相当老了,并且System.arraycopy已经被充分讨论过了,最好避免唤起旧的帖子,除非回复对该帖子做出了重要贡献。 - Leigh
1
这不是拼接而是复制。目标必须已经有足够的空间来容纳所有源,否则上述代码将导致ArrayIndexOutOfBoundsException异常。 - Adriaan Koster

-1

应该可以解决问题。这是假设 String[] first 和 String[] second 的情况。

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()]);

myList.addAll(new ArrayList<String>(Arrays.asList(second))); can be simplified to myList.addAll(Arrays.asList(second)) - slartidan

-1
在Haskell中,您可以像这样做:[a, b, c] ++ [d, e]以获取[a, b, c, d, e]。 这些是Haskell列表连接起来的,但是如果Java有一个类似的运算符来操作数组将非常好。 您不认为吗?这很优雅,简单,通用,并且实现起来并不那么困难。
如果您愿意,我建议您看看Alexander Hristov在他的Hacking the OpenJDK compiler中的工作。 他解释了如何修改javac源代码以创建新的运算符。 他的例子包括定义一个'**'运算符,其中i ** j = Math.pow(i, j)。 可以借鉴这个例子来实现一个连接两个相同类型数组的运算符。

一旦你这样做了,你就会被绑定到你自定义的javac来编译你的代码,但生成的字节码将被任何JVM理解。

当然,你可以在源代码级别实现自己的数组连接方法,在其他答案中有许多示例!

有很多有用的运算符可以添加,这个运算符将是其中之一。


哇,不错!为什么不更换编译器来解决Java语法问题呢?:) 大胆的举动! - Synox

-1
    void f(String[] first, String[] second) {
    String[] both = new String[first.length+second.length];
    for(int i=0;i<first.length;i++)
        both[i] = first[i];
    for(int i=0;i<second.length;i++)
        both[first.length + i] = second[i];
}

这个方法不需要任何其他类/库的知识。 它适用于任何数据类型。只需将String替换为任何东西,如intdoublechar。 它的效率相当高。


CPU和内存的浪费。请参考@Douglas-Held的答案。 - Rudra

-2

这是对我有用的内容:

String[] data=null;
String[] data2=null;
ArrayList<String> data1 = new ArrayList<String>();
for(int i=0; i<2;i++) {
   data2 = input.readLine().split(",");
   data1.addAll(Arrays.asList(data2));
   data= data1.toArray(new String[data1.size()]);
   }

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