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

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

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

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

1305783 次浏览

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

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

我从旧的Apache Commons Lang库中找到了一个单行解决方案。
#0

代码:

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

功能Java库有一个数组包装类,它为数组配备了方便的方法,如连接。

import static fj.data.Array.array;

…然后

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

要获取未包装的数组,请调用

String[] s = both.array();

仅使用Javas自己的API:

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

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

以下是silvertab解决方案的改编,并对泛型进行了改造:

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的回答以获得Java6的解决方案。它不仅消除了警告;它还更短,更高效,更易于阅读!

我最近遇到了内存过度旋转的问题。如果已知a和/或b通常为空,这是silvertab代码的另一个改编(也经过泛化):

private static <T> T[] concatOrReturnSame(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;}

编辑:这篇文章的上一个版本说过,像这样的数组重用应该被清楚地记录下来。正如Maarten在评论中指出的那样,通常最好删除if语句,这样就不需要留档了。但话说回来,那些if语句首先是这次特定优化的全部意义。我会把这个答案留在这里,但要小心!

使用JavaAPI:

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

如果您想在解决方案中使用ArrayList,您可以尝试以下操作:

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

我测试了下面的代码并工作正常

我也使用库:org.apache.commons.lang.ArrayUtils

public void testConcatArrayString(){String[] a = null;String[] b = null;String[] c = null;a = new String[] {"1","2","3","4","5"};b = new String[] {"A","B","C","D","E"};
c = (String[]) ArrayUtils.addAll(a, b);if(c!=null){for(int i=0; i<c.length; i++){System.out.println("c[" + (i+1) + "] = " + c[i]);}}}

问候

这可以,但您需要插入自己的错误检查。

public class StringConcatenate {
public static void main(String[] args){
// Create two arrays to concatenate and one array to hold bothString[] 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 arrayfor(int i = 0; i < arr1.length; i++){arrBoth[i] = arr1[i];}
// Copy elements from second array into last part of new arrayfor(int j = arr1.length;j < arrBoth.length;j++){arrBoth[j] = arr2[j-arr1.length];}
// Print resultfor(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以外的任何东西。

可以编写一个完全通用的版本,甚至可以扩展到连接任意数量的数组。此版本需要Java6,因为它们使用#0

两个版本都避免创建任何中间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;}

一种简单但效率低下的方法(不包括泛型):

ArrayList baseArray = new ArrayList(Arrays.asList(array1));baseArray.addAll(Arrays.asList(array2));String concatenated[] = (String []) baseArray.toArray(new String[baseArray.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()]);}

一个与类型无关的变体(更新-感谢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()));}
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;}

另一个基于SilverTab的建议,但支持x个参数,不需要Java6。它也不是通用的,但我相信它可以变得通用。

private byte[] concat(byte[]... args){int fulllength = 0;for (byte[] arrItem : args){fulllength += arrItem.length;}byte[] retArray = new byte[fulllength];int start = 0;for (byte[] arrItem : args){System.arraycopy(arrItem, 0, retArray, start, arrItem.length);start += arrItem.length;}return retArray;}

心爱的人番石榴

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

这是我对Joachim Sauer的concatAll的略微改进版本。它可以在Java5或6上工作,使用Java6的System.arraycopy如果它在运行时可用。这种方法(IMHO)非常适合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" approachresult = (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;}

我能找到的最简单的方法如下:

List allFiltersList = Arrays.asList(regularFilters);allFiltersList.addAll(Arrays.asList(preFiltersArray));Filter[] mergedFilterArray = (Filter[]) allFiltersList.toArray();

这是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;}
Import java.util.*;
String array1[] = {"bla","bla"};String array2[] = {"bla","bla"};
ArrayList<String> tempArray = new ArrayList<String>(Arrays.asList(array1));tempArray.addAll(Arrays.asList(array2));String array3[] = films.toArray(new String[1]); // size will be overwritten if needed

您可以将String替换为您喜欢的类型/类

我相信这可以变得更短更好,但它有效,我懒得进一步整理它……

你可以试试这个

 public static Object[] addTwoArray(Object[] objArr1, Object[] objArr2){int arr1Length = objArr1!=null && objArr1.length>0?objArr1.length:0;int arr2Length = objArr2!=null && objArr2.length>0?objArr2.length:0;Object[] resutlentArray = new Object[arr1Length+arr2Length];for(int i=0,j=0;i<resutlentArray.length;i++){if(i+1<=arr1Length){resutlentArray[i]=objArr1[i];}else{resutlentArray[i]=objArr2[j];j++;}}
return resutlentArray;}

你可以键入cast你的数组!!!

解决方案100%旧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;}

不如干脆

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

只要arr1arr2属于相同类型,这将为您提供另一个包含这两个数组的相同类型的数组。

这里是silvertab编写的伪代码解决方案的工作代码中的可能实现。

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

接下来是构建器界面。

注意:构建器是必要的,因为在java中它是不可能的

new T[size]

由于泛型类型擦除:

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

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

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

最后是应用程序/测试:

@Testpublic 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]);}}

在Haskell中,您可以执行类似于[a, b, c] ++ [d, e]的操作来获得[a, b, c, d, e]。这些是连接的Haskell列表,但在数组Java中看到类似的运算符会很好。你不这么认为吗?这很优雅,简单,通用,实现起来并不难。

如果你愿意,我建议你看看Alexander Hristov在他的破解OpenJDK编译器中的工作。他解释了如何修改javac源代码以创建一个新的运算符。他的例子包括在i ** j = Math.pow(i, j)的位置定义一个“**”运算符。可以拿这个例子来实现一个连接两个相同类型数组的运算符。

完成后,您将绑定到自定义的javac来编译代码,但生成的字节码将被任何JVM理解。

当然,您可以在源代码级别实现自己的数组连接方法,在其他答案中有很多关于如何做到这一点的示例!

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

看看这个优雅的解决方案(如果您需要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;}}

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

我发现我必须处理数组可以为空的情况…

private double[] concat  (double[]a,double[]b){if (a == null) return b;if (b == null) return a;double[] r = new double[a.length+b.length];System.arraycopy(a, 0, r, 0, a.length);System.arraycopy(b, 0, r, a.length, b.length);return r;
}private double[] copyRest (double[]a, int start){if (a == null) return null;if (start > a.length)return null;double[]r = new double[a.length-start];System.arraycopy(a,start,r,0,a.length-start);return r;}

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

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

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

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

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

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

我相信上面的等效于使用System.arraycopy的解决方案。然而,我认为这个有它自己的美。

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

应该做到这一点。这假设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()]);

这个仅适用于int,但这个想法是通用的

public static int[] junta(int[] v, int[] w) {
int[] junta = new int[v.length + w.length];
for (int i = 0; i < v.length; i++) {junta[i] = v[i];}
for (int j = v.length; j < junta.length; j++) {junta[j] = w[j - v.length];}

在Java8中使用#0

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

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

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

不如:

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

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

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

Java8使用Stream的另一种方式

  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);}
public static String[] toArray(String[]... object){List<String> list=new ArrayList<>();for (String[] i : object) {list.addAll(Arrays.asList(i));}return list.toArray(new String[list.size()]);}
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;

每一个答案都是复制数据并创建一个新数组。这不是绝对必要的,如果你的数组相当大,这绝对不是你想要做的。Java创建者已经知道数组副本是浪费的,这就是为什么他们为我们提供了System.arrayCopy()来在必要时执行外部Java。

与其四处复制数据,不如考虑将其留在原地并从中提取数据。仅仅因为程序员想要组织它们而复制数据位置并不总是明智的。

// I have arrayA and arrayB; would like to treat them as concatenated// but leave my damn bytes where they are!Object accessElement ( int index ) {if ( index < 0 ) throw new ArrayIndexOutOfBoundsException(...);// is reading from the head part?if ( index < arrayA.length )return arrayA[ index ];// is reading from the tail part?if ( index < ( arrayA.length + arrayB.length ) )return arrayB[ index - arrayA.length ];throw new ArrayIndexOutOfBoundsException(...); // index too large}

这是算术软件的代码。

String[] a = {"a", "b", "c"};String[] b = {"1", "2", "3"};String[] c = N.concat(a, b); // c = ["a", "b", "c", "1", "2", "3"]
// N.concat(...) is null-safety.a = null;c = N.concat(a, b); // c = ["1", "2", "3"]
    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之类的东西。工作效率很高

如果您使用这种方式,则无需导入任何第三方类。

如果你想连接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;}

这里是Main方法

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

我们也可以用这种方法。

算法爱好者的另一个答案:

public static String[] mergeArrays(String[] array1, String[] array2) {int totalSize = array1.length + array2.length; // Get total sizeString[] merged = new String[totalSize]; // Create new array// Loop over the total sizefor (int i = 0; i < totalSize; i++) {if (i < array1.length) // If the current position is less than the length of the first array, take value from first arraymerged[i] = array1[i]; // Position in first array is the current position
else // If current position is equal or greater than the first array, take value from second array.merged[i] = array2[i - array1.length]; // Position in second array is current position minus length of first array.}
return merged;

用法:

String[] array1str = new String[]{"a", "b", "c", "d"};String[] array2str = new String[]{"e", "f", "g", "h", "i"};String[] listTotalstr = mergeArrays(array1str, array2str);System.out.println(Arrays.toString(listTotalstr));

结果:

[a, b, c, d, e, f, g, h, i]

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

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[] both = Arrays.copyOf(first, first.length + second.length);System.arraycopy(second, 0, both, first.length, second.length);

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

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

对于大型数组,您应该避免for循环,因为这些循环效率低下。内置方法使用非常快的块复制函数。

Java8

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

非Java解决方案:

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

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

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

这应该是单线的。

public String [] concatenate (final String array1[], final String array2[]){return Stream.concat(Stream.of(array1), Stream.of(array2)).toArray(String[]::new);}

使用高性能System.arraycopy的通用静态版本,不需要@SuppressWarning注释:

public static <T> T[] arrayConcat(T[] a, T[] b) {T[] both = Arrays.copyOf(a, a.length + b.length);System.arraycopy(b, 0, both, a.length, b.length);return both;}

这可能是唯一的泛型和类型安全的方法:

public class ArrayConcatenator<T> {private final IntFunction<T[]> generator;
private ArrayConcatenator(IntFunction<T[]> generator) {this.generator = generator;}
public static <T> ArrayConcatenator<T> concat(IntFunction<T[]> generator) {return new ArrayConcatenator<>(generator);}
public T[] apply(T[] array1, T[] array2) {T[] array = generator.apply(array1.length + array2.length);System.arraycopy(array1, 0, array, 0, array1.length);System.arraycopy(array2, 0, array, array1.length, array2.length);return array;}}

用法非常简洁:

Integer[] array1 = { 1, 2, 3 };Double[] array2 = { 4.0, 5.0, 6.0 };Number[] array = concat(Number[]::new).apply(array1, array2);

(需要静态导入)

无效的数组类型被拒绝:

concat(String[]::new).apply(array1, array2); // errorconcat(Integer[]::new).apply(array1, array2); // error

使用lambda连接一系列紧凑、快速且类型安全的数组

@SafeVarargspublic static <T> T[] concat( T[]... arrays ) {return( Stream.of( arrays ).reduce( ( arr1, arr2 ) -> {T[] rslt = Arrays.copyOf( arr1, arr1.length + arr2.length );System.arraycopy( arr2, 0, rslt, arr1.length, arr2.length );return( rslt );} ).orElse( null ) );};

无参数调用时返回null

例如。带有3个数组的示例:

String[] a = new String[] { "a", "b", "c", "d" };String[] b = new String[] { "e", "f", "g", "h" };String[] c = new String[] { "i", "j", "k", "l" };
concat( a, b, c );  // [a, b, c, d, e, f, g, h, i, j, k, l]


"…可能是唯一通用且类型安全的方法"-改编:

Number[] array1 = { 1, 2, 3 };Number[] array2 = { 4.0, 5.0, 6.0 };Number[] array = concat( array1, array2 );  // [1, 2, 3, 4.0, 5.0, 6.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("===");}}

以下是对我有用的:

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

我使用next方法使用java 8连接任意数量的相同类型的数组:

public static <G> G[] concatenate(IntFunction<G[]> generator, G[] ... arrays) {int len = arrays.length;if (len == 0) {return generator.apply(0);} else if (len == 1) {return arrays[0];}int pos = 0;Stream<G> result = Stream.concat(Arrays.stream(arrays[pos]), Arrays.stream(arrays[++pos]));while (pos < len - 1) {result = Stream.concat(result, Arrays.stream(arrays[++pos]));}return result.toArray(generator);}

用法:

 concatenate(String[]::new, new String[]{"one"}, new String[]{"two"}, new String[]{"three"})

 concatenate(Integer[]::new, new Integer[]{1}, new Integer[]{2}, new Integer[]{3})

这个问题我也是刚刚才发现,抱歉很晚,看到很多答案都离得太远,使用某些库,使用将数据从数组转换为流并返回数组的特性等等。但是,我们可以只使用一个简单的循环,问题就解决了

public String[] concat(String[] firstArr,String[] secondArr){//if both is empty just returnif(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 secondArrfor(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;}

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

我有一个简单的方法。你不想浪费时间研究复杂的java函数或库。但返回类型应该是String。

String[] f(String[] first, String[] second) {
// Variable declaration partint 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;
}

这么简单…

使用Java集合

Java没有提供连接数组的辅助方法。但是,从Java5开始,Colltions实用程序类引入了addAll(Collection<?超T>c, T…元素)方法。

我们可以创建一个List对象,然后两次调用此方法将两个数组添加到列表中。最后,我们将生成的List转换回数组:

static <T> T[] concatWithCollection(T[] array1, T[] array2) {List<T> resultList = new ArrayList<>(array1.length + array2.length);Collections.addAll(resultList, array1);Collections.addAll(resultList, array2);
@SuppressWarnings("unchecked")//the type cast is safe as the array1 has the type T[]T[] resultArray = (T[]) Array.newInstance(array1.getClass().getComponentType(), 0);return resultList.toArray(resultArray);}

测试

@Testpublic void givenTwoStringArrays_whenConcatWithList_thenGetExpectedResult() {String[] result = ArrayConcatUtil.concatWithCollection(strArray1, strArray2);assertThat(result).isEqualTo(expectedStringArray);}

我看到许多带有签名的通用答案,例如public静态T[]concat(T[]a, T[]b){},但据我所知,这些仅适用于Object数组,不适用于原始数组。下面的代码适用于Object和原始数组,使其更通用…

public static <T> T concat(T a, T b) {//Handles both arrays of Objects and primitives! E.g., int[] out = concat(new int[]{6,7,8}, new int[]{9,10});//You get a compile error if argument(s) not same type as output. (int[] in example above)//You get a runtime error if output type is not an array, i.e., when you do something like: int out = concat(6,7);if (a == null && b == null) return null;if (a == null) return b;if (b == null) return a;final int aLen = Array.getLength(a);final int bLen = Array.getLength(b);if (aLen == 0) return b;if (bLen == 0) return a;//From here on we really need to concatenate!
Class componentType = a.getClass().getComponentType();final T result = (T)Array.newInstance(componentType, aLen + bLen);System.arraycopy(a, 0, result, 0, aLen);System.arraycopy(b, 0, result, aLen, bLen);return result;}
public static void main(String[] args) {String[] out1 = concat(new String[]{"aap", "monkey"}, new String[]{"rat"});int[] out2 = concat(new int[]{6,7,8}, new int[]{9,10});}
 /*** 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);}