我怎样才能在Java中连接两个数组?

我需要在Java中连接两个string数组。

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

什么是最简单的方法来做到这一点?

我从老的Apache Commons Lang库中find了一个单行的解决scheme。
ArrayUtils.addAll(T[], T...)

码:

 String[] both = (String[])ArrayUtils.addAll(first, second); 

这里有一个连接2个Footypes的数组的方法(代码中的Foo和你的类名相同)。

 public Foo[] concat(Foo[] a, Foo[] b) { int aLen = a.length; int bLen = b.length; Foo[] c= new Foo[aLen+bLen]; System.arraycopy(a, 0, c, 0, aLen); System.arraycopy(b, 0, c, aLen, bLen); return c; } 

(来源: Sun论坛 )

这是一个与generics兼容的版本:

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

请注意,像所有的generics一样,它不能与基元一起使用,但是使用对象。

编写一个完全通用的版本是可能的,甚至可以扩展连接任意数量的数组。 这个版本需要Java 6,因为他们使用Arrays.copyOf()

两个版本都避免了创build任何中间的List对象,并使用System.arraycopy()来确保复制大型数组的速度尽可能快。

对于两个数组,看起来像这样:

 public static <T> T[] concat(T[] first, T[] second) { T[] result = Arrays.copyOf(first, first.length + second.length); System.arraycopy(second, 0, result, first.length, second.length); return result; } 

对于任意数量的数组(> = 1),它看起来像这样:

 public static <T> T[] concatAll(T[] first, T[]... rest) { int totalLength = first.length; for (T[] array : rest) { totalLength += array.length; } T[] result = Arrays.copyOf(first, totalLength); int offset = first.length; for (T[] array : rest) { System.arraycopy(array, 0, result, offset, array.length); offset += array.length; } return result; } 

Java中的单线程8:

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

要么:

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

或与心爱的番石榴 :

 String[] both = ObjectArrays.concat(first, second, String.class); 

此外,还有基本数组的版本:

  • Booleans.concat(first, second)
  • Bytes.concat(first, second)
  • Chars.concat(first, second)
  • Doubles.concat(first, second)
  • Shorts.concat(first, second)
  • Ints.concat(first, second)
  • Longs.concat(first, second)
  • Floats.concat(first, second)

使用Java API:

 String[] f(String[] first, String[] second) { List<String> both = new ArrayList<String>(first.length + second.length); Collections.addAll(both, first); Collections.addAll(both, second); return both.toArray(new String[both.size()]); } 

一个解决scheme100%的Java没有 System.arraycopy (例如在GWT客户端中不可用):

 static String[] concat(String[]... arrays) { int length = 0; for (String[] array : arrays) { length += array.length; } String[] result = new String[length]; int pos = 0; for (String[] array : arrays) { for (String element : array) { result[pos] = element; pos++; } } return result; } 

我最近遇到过度旋转内存的问题。 如果已知a和/或b通常是空的,这里是silvertab的代码的另一个适应(也被基因化了):

 private static <T> T[] concat(T[] a, T[] b) { final int alen = a.length; final int blen = b.length; if (alen == 0) { return b; } if (blen == 0) { return a; } 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; } 

(无论哪种情况,arrays重用行为都应该清楚JavaDoced!)

Functional Java库有一个数组封装类,它为数组提供了像串接这样的方便的方法。

 import static fj.data.Array.array; 

…接着

 Array<String> both = array(first).append(array(second)); 

要取出展开的数组,请调用

 String[] s = both.array(); 

以下是对silvertab解决scheme的改进,对generics进行了改进:

 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解决scheme的回答 。 它不仅消除了警告, 它也更短,更高效,更容易阅读!

使用Stream的Java8的另一种方法

  public String[] concatString(String[] a, String[] b){ Stream<String> streamA = Arrays.stream(a); Stream<String> streamB = Arrays.stream(b); return Stream.concat(streamA, streamB).toArray(String[]::new); } 
 ArrayList<String> both = new ArrayList(Arrays.asList(first)); both.addAll(Arrays.asList(second)); both.toArray(); 

如果你使用这种方式,所以你不需要导入任何第三方类。

如果你想连接String

连接两个string数组的示例代码

 public static String[] combineString(String[] first, String[] second){ int length = first.length + second.length; String[] result = new String[length]; System.arraycopy(first, 0, result, 0, first.length); System.arraycopy(second, 0, result, first.length, second.length); return result; } 

如果你想连接Int

连接两个整数数组的示例代码

 public static int[] combineInt(int[] a, int[] b){ int length = a.length + b.length; int[] result = new int[length]; System.arraycopy(a, 0, result, 0, a.length); System.arraycopy(b, 0, result, a.length, b.length); return result; } 

这里是主要方法

  public static void main(String[] args) { String [] first = {"a", "b", "c"}; String [] second = {"d", "e"}; String [] joined = combineString(first, second); System.out.println("concatenated String array : " + Arrays.toString(joined)); int[] array1 = {101,102,103,104}; int[] array2 = {105,106,107,108}; int[] concatenateInt = combineInt(array1, array2); System.out.println("concatenated Int array : " + Arrays.toString(concatenateInt)); } } 

我们也可以用这种方式。

请原谅我为这个已经很长的列表添加另一个版本。 我查看了每一个答案,并决定我真的想要一个只有签名中的一个参数的版本。 我还添加了一些参数检查,以便在出现意外input的情况下从早期的失败中获益。

 @SuppressWarnings("unchecked") public static <T> T[] concat(T[]... inputArrays) { if(inputArrays.length < 2) { throw new IllegalArgumentException("inputArrays must contain at least 2 arrays"); } for(int i = 0; i < inputArrays.length; i++) { if(inputArrays[i] == null) { throw new IllegalArgumentException("inputArrays[" + i + "] is null"); } } int totalLength = 0; for(T[] array : inputArrays) { totalLength += array.length; } T[] result = (T[]) Array.newInstance(inputArrays[0].getClass().getComponentType(), totalLength); int offset = 0; for(T[] array : inputArrays) { System.arraycopy(array, 0, result, offset, array.length); offset += array.length; } return result; } 

您可以尝试将其转换为Arraylist并使用addAll方法,然后转换回数组。

 List list = new ArrayList(Arrays.asList(first)); list.addAll(Arrays.asList(second)); String[] both = list.toArray(); 

这里是由silvertab编写的伪代码解决scheme的工作代码中的一个可能的实现。

感谢silvertab!

 public class Array { public static <T> T[] concat(T[] a, T[] b, ArrayBuilderI<T> builder) { T[] c = builder.build(a.length + b.length); System.arraycopy(a, 0, c, 0, a.length); System.arraycopy(b, 0, c, a.length, b.length); return c; } } 

接下来是构build器界面。

注意:构build器是必需的,因为在java中是不可能的

new T[size]

由于generics擦除:

 public interface ArrayBuilderI<T> { public T[] build(int size); } 

这里是一个实现接口的具体构build器,构build一个Integer数组:

 public class IntegerArrayBuilder implements ArrayBuilderI<Integer> { @Override public Integer[] build(int size) { return new Integer[size]; } } 

最后是应用程序/testing:

 @Test public class ArrayTest { public void array_concatenation() { Integer a[] = new Integer[]{0,1}; Integer b[] = new Integer[]{2,3}; Integer c[] = Array.concat(a, b, new IntegerArrayBuilder()); assertEquals(4, c.length); assertEquals(0, (int)c[0]); assertEquals(1, (int)c[1]); assertEquals(2, (int)c[2]); assertEquals(3, (int)c[3]); } } 

哇! 这里有很多复杂的答案,包括一些依赖外部依赖的简单答案。 怎么样这样做:

 String [] arg1 = new String{"a","b","c"}; String [] arg2 = new String{"x","y","z"}; ArrayList<String> temp = new ArrayList<String>(); temp.addAll(Arrays.asList(arg1)); temp.addAll(Arrays.asList(arg2)); String [] concatedArgs = temp.toArray(new String[arg1.length+arg2.length]); 

这是一个string数组的转换函数:

 public String[] mergeArrays(String[] mainArray, String[] addArray) { String[] finalArray = new String[mainArray.length + addArray.length]; System.arraycopy(mainArray, 0, finalArray, 0, mainArray.length); System.arraycopy(addArray, 0, finalArray, mainArray.length, addArray.length); return finalArray; } 

如何简单

 public static class Array { public static <T> T[] concat(T[]... arrays) { ArrayList<T> al = new ArrayList<T>(); for (T[] one : arrays) Collections.addAll(al, one); return (T[]) al.toArray(arrays[0].clone()); } } 

只要做Array.concat(arr1, arr2) 。 只要arr1arr2是相同的types,这将给你另一个包含两个数组的同一types的数组。

只使用Java自己的API:

 String[] join(String[]... arrays) { // calculate size of target array int size = 0; for (String[] array : arrays) { size += array.length; } // create list of appropriate size java.util.List list = new java.util.ArrayList(size); // add arrays for (String[] array : arrays) { list.addAll(java.util.Arrays.asList(array)); } // create and return final array return list.toArray(new String[size]); } 

现在,这个代码并不是最高效的,但它只依赖于标准的java类,而且很容易理解。 它适用于任何数量的String [](甚至是零数组)。

这是我稍微改进的Joachim Sauer的concatAll版本。 它可以在Java 5或6上工作,如果在运行时可用,则使用Java 6的System.arraycopy。 这个方法(恕我直言)是Android的完美,因为它在Android <9(没有System.arraycopy),但将尽可能使用更快的方法。

  public static <T> T[] concatAll(T[] first, T[]... rest) { int totalLength = first.length; for (T[] array : rest) { totalLength += array.length; } T[] result; try { Method arraysCopyOf = Arrays.class.getMethod("copyOf", Object[].class, int.class); result = (T[]) arraysCopyOf.invoke(null, first, totalLength); } catch (Exception e){ //Java 6 / Android >= 9 way didn't work, so use the "traditional" approach result = (T[]) java.lang.reflect.Array.newInstance(first.getClass().getComponentType(), totalLength); System.arraycopy(first, 0, result, 0, first.length); } int offset = first.length; for (T[] array : rest) { System.arraycopy(array, 0, result, offset, array.length); offset += array.length; } return result; } 

另一种思考问题的方式。 要连接两个或多个数组,需要做的是列出每个数组的所有元素,然后构build一个新的数组。 这听起来像创build一个List<T> ,然后调用它的toArray 。 其他一些答案使用ArrayList ,这很好。 但是如何实现我们自己的? 这并不难:

 private static <T> T[] addAll(final T[] f, final T...o){ return new AbstractList<T>(){ @Override public T get(int i) { return i>=f.length ? o[i - f.length] : f[i]; } @Override public int size() { return f.length + o.length; } }.toArray(f); } 

我相信以上相当于使用System.arraycopy解决scheme。 不过我觉得这个有自己的美感。

怎么样 :

 public String[] combineArray (String[] ... strings) { List<String> tmpList = new ArrayList<String>(); for (int i = 0; i < strings.length; i++) tmpList.addAll(Arrays.asList(strings[i])); return tmpList.toArray(new String[tmpList.size()]); } 

允许连接多个数组的简单变体:

 public static String[] join(String[]...arrays) { final List<String> output = new ArrayList<String>(); for(String[] array : arrays) { output.addAll(Arrays.asList(array)); } return output.toArray(new String[output.size()]); } 

这工作,但你需要插入自己的错误检查。

 public class StringConcatenate { public static void main(String[] args){ // Create two arrays to concatenate and one array to hold both String[] arr1 = new String[]{"s","t","r","i","n","g"}; String[] arr2 = new String[]{"s","t","r","i","n","g"}; String[] arrBoth = new String[arr1.length+arr2.length]; // Copy elements from first array into first part of new array for(int i = 0; i < arr1.length; i++){ arrBoth[i] = arr1[i]; } // Copy elements from second array into last part of new array for(int j = arr1.length;j < arrBoth.length;j++){ arrBoth[j] = arr2[j-arr1.length]; } // Print result for(int k = 0; k < arrBoth.length; k++){ System.out.print(arrBoth[k]); } // Additional line to make your terminal look better at completion! System.out.println(); } } 

这可能不是最高效的,但它不依赖于Java自己的API以外的任何东西。

 String [] both = new ArrayList<String>(){{addAll(Arrays.asList(first)); addAll(Arrays.asList(second));}}.toArray(new String[0]); 

独立于types的变体(更新 – 感谢Volley实例化T):

 @SuppressWarnings("unchecked") public static <T> T[] join(T[]...arrays) { final List<T> output = new ArrayList<T>(); for(T[] array : arrays) { output.addAll(Arrays.asList(array)); } return output.toArray((T[])Array.newInstance( arrays[0].getClass().getComponentType(), output.size())); } 

如果你想在解决scheme中使用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()]); } 

一个简单而低效的方法来做到这一点(不包括generics):

 ArrayList baseArray = new ArrayList(Arrays.asList(array1)); baseArray.addAll(Arrays.asList(array2)); String concatenated[] = (String []) baseArray.toArray(new String[baseArray.size()]); 
 public String[] concat(String[]... arrays) { int length = 0; for (String[] array : arrays) { length += array.length; } String[] result = new String[length]; int destPos = 0; for (String[] array : arrays) { System.arraycopy(array, 0, result, destPos, array.length); destPos += array.length; } return result; }