简体   繁体   English

如何在 Java 中连接两个 arrays?

[英]How can I concatenate two arrays in Java?

I need to concatenate two String arrays in Java.我需要在 Java 中连接两个String arrays。

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

Which is the easiest way to do this?哪种方法最简单?

I found a one-line solution from the good old Apache Commons Lang library.我从古老的 Apache Commons Lang 库中找到了一个单行解决方案。
ArrayUtils.addAll(T[], T...)

Code:代码:

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

Here's a simple method that will concatenate two arrays and return the 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;
}

Note that it will not work with primitive data types, only with object types.请注意,它不适用于原始数据类型,只能用于对象类型。

The following slightly more complicated version works with both object and primitive arrays.以下稍微复杂的版本适用于对象和原始数组。 It does this by using T instead of T[] as the argument type.它通过使用T而不是T[]作为参数类型来做到这一点。

It also makes it possible to concatenate arrays of two different types by picking the most general type as the component type of the result.它还可以通过选择最通用的类​​型作为结果的组件类型来连接两种不同类型的数组。

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

Here is an example:下面是一个例子:

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

Using Stream in Java 8:在 Java 8 中使用Stream

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

Or like this, using flatMap :或者像这样,使用flatMap

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

To do this for a generic type you have to use reflection:要对泛型类型执行此操作,您必须使用反射:

@SuppressWarnings("unchecked")
T[] both = Stream.concat(Arrays.stream(a), Arrays.stream(b)).toArray(
    size -> (T[]) Array.newInstance(a.getClass().getComponentType(), size));

It's possible to write a fully generic version that can even be extended to concatenate any number of arrays.可以编写一个完全通用的版本,甚至可以扩展它以连接任意数量的数组。 This versions require Java 6, as they use Arrays.copyOf()此版本需要 Java 6,因为它们使用Arrays.copyOf()

Both versions avoid creating any intermediary List objects and use System.arraycopy() to ensure that copying large arrays is as fast as possible.两个版本都避免创建任何中间List对象并使用System.arraycopy()来确保尽可能快地复制大型数组。

For two arrays it looks like this:对于两个数组,它看起来像这样:

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

And for a arbitrary number of arrays (>= 1) it looks like this:对于任意数量的数组 (>= 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;
}

Or with the beloved Guava :或与心爱的番石榴

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

Also, there are versions for primitive arrays:此外,还有原始数组的版本:

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

You can append the two arrays in two lines of code.您可以在两行代码中附加这两个数组。

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

This is a fast and efficient solution and will work for primitive types as well as the two methods involved are overloaded.这是一个快速有效的解决方案,适用于原始类型以及所涉及的两个方法被重载。

You should avoid solutions involving ArrayLists, streams, etc as these will need to allocate temporary memory for no useful purpose.您应该避免涉及 ArrayLists、streams 等的解决方案,因为这些将需要分配临时内存而没有任何用处。

You should avoid for loops for large arrays as these are not efficient.您应该避免大型数组的for循环,因为它们效率不高。 The built in methods use block-copy functions that are extremely fast.内置方法使用非常快的块复制功能。

Using the Java API:使用 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()]);
}

A solution 100% old java and without System.arraycopy (not available in GWT client for example):一个解决方案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;
}

I've recently fought problems with excessive memory rotation.我最近解决了过度内存轮换的问题。 If a and/or b are known to be commonly empty, here is another adaption of silvertab's code (generified too):如果已知 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;
}

Edit: A previous version of this post stated that array re-usage like this shall be clearly documented.编辑:这篇文章的前一个版本指出,像这样的数组重用应该被清楚地记录下来。 As Maarten points out in the comments it would in general be better to just remove the if statements, thus voiding the need for having documentation.正如 Maarten 在评论中指出的那样,通常最好只删除 if 语句,从而无需拥有文档。 But then again, those if statements were the whole point of this particular optimization in the first place.但话又说回来,那些 if 语句首先是这个特定优化的重点。 I'll leave this answer here, but be wary!我会在这里留下这个答案,但要小心!

ArrayList<String> both = new ArrayList(Arrays.asList(first));
both.addAll(Arrays.asList(second));

both.toArray(new String[0]);

The Functional Java library has an array wrapper class that equips arrays with handy methods like concatenation. Functional Java库有一个数组包装类,它为数组配备了一些方便的方法,比如连接。

import static fj.data.Array.array;

...and then ...进而

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

To get the unwrapped array back out, call要取回未包装的数组,请调用

String[] s = both.array();

Another way with Java8 using Stream 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); 
  }

Here's an adaptation of silvertab's solution, with generics retrofitted:这是 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;
}

NOTE: See Joachim's answer for a Java 6 solution.注意:有关 Java 6 解决方案,请参阅Joachim 的回答 Not only does it eliminate the warning;它不仅消除了警告; it's also shorter, more efficient and easier to read!它也更短、更高效、更容易阅读!

You could try converting it into a Arraylist and use the addAll method then convert back to an array.您可以尝试将其转换为 Arraylist 并使用 addAll 方法,然后再转换回数组。

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

If you use this way so you no need to import any third party class.如果您使用这种方式,则无需导入任何第三方类。

If you want concatenate String如果你想连接String

Sample code for concate two String Array连接两个字符串数组的示例代码

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

If you want concatenate Int如果你想连接Int

Sample code for concate two Integer Array连接两个整数数组的示例代码

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

Here is Main method这是主要方法

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

        }
    }  

We can use this way also.我们也可以使用这种方式。

Please forgive me for adding yet another version to this already long list.请原谅我在这个已经很长的列表中添加了另一个版本。 I looked at every answer and decided that I really wanted a version with just one parameter in the signature.我查看了每个答案,并决定我真的想要一个签名中只有一个参数的版本。 I also added some argument checking to benefit from early failure with sensible info in case of unexpected 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;
}

Using Java 8+ streams you can write the following function:使用 Java 8+ 流,您可以编写以下函数:

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

This should be one-liner.这应该是单行的。

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

Here a possible implementation in working code of the pseudo code solution written by silvertab.这是silvertab编写的伪代码解决方案的工作代码中的可能实现。

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

Following next is the builder interface.接下来是构建器界面。

Note: A builder is necessary because in java it is not possible to do注意:构建器是必需的,因为在 Java 中这是不可能的

new T[size]

due to generic type erasure:由于泛型类型擦除:

public interface ArrayBuilderI<T> {

   public T[] build(int size);
}

Here a concrete builder implementing the interface, building a Integer array:这是一个实现接口的具体构建器,构建一个Integer数组:

public class IntegerArrayBuilder implements ArrayBuilderI<Integer> {

   @Override
   public Integer[] build(int size) {
      return new Integer[size];
   }
}

And finally the application / test:最后是应用程序/测试:

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

Wow!哇! lot of complex answers here including some simple ones that depend on external dependencies.这里有很多复杂的答案,包括一些依赖于外部依赖的简单答案。 how about doing it like this:这样做怎么样:

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

This works, but you need to insert your own error checking.这有效,但您需要插入自己的错误检查。

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

It's probably not the most efficient, but it doesn't rely on anything other than Java's own API.它可能不是最有效的,但它不依赖于 Java 自己的 API 以外的任何东西。

A simple variation allowing the joining of more than one array:一种允许连接多个数组的简单变体:

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

A generic static version that uses the high performing System.arraycopy without requiring a @SuppressWarnings annotation:使用高性能 System.arraycopy 而不需要 @SuppressWarnings 注释的通用静态版本:

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

This is a converted function for a String array:这是字符串数组的转换函数:

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

How about simply简单的怎么样

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

And just do Array.concat(arr1, arr2) .只需执行Array.concat(arr1, arr2) As long as arr1 and arr2 are of the same type, this will give you another array of the same type containing both arrays.只要arr1arr2的类型相同,这将为您提供另一个包含两个数组的相同类型的数组。

Another way to think about the question.思考这个问题的另一种方式。 To concatenate two or more arrays, one have to do is to list all elements of each arrays, and then build a new array.要连接两个或多个数组,必须列出每个数组的所有元素,然后构建一个新数组。 This sounds like create a List<T> and then calls toArray on it.这听起来像是创建一个List<T>然后在其上调用toArray Some other answers uses ArrayList , and that's fine.其他一些答案使用ArrayList ,这很好。 But how about implement our own?但是如何实现我们自己的呢? It is not hard:这并不难:

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

I believe the above is equivalent to solutions that uses System.arraycopy .我相信以上相当于使用System.arraycopy解决方案。 However I think this one has its own beauty.不过我觉得这个有它自己的美。

How about :怎么样 :

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

I need to concatenate two String arrays in Java.我需要在Java中串联两个String数组。

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

What is the easiest way to do this?最简单的方法是什么?

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

Here's my slightly improved version of Joachim Sauer's concatAll.这是我对 Joachim Sauer 的 concatAll 稍加改进的版本。 It can work on Java 5 or 6, using Java 6's System.arraycopy if it's available at runtime.它可以在 Java 5 或 6 上运行,如果它在运行时可用,则使用 Java 6 的 System.arraycopy。 This method (IMHO) is perfect for Android, as it work on Android <9 (which doesn't have System.arraycopy) but will use the faster method if possible.这种方法(恕我直言)非常适合 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;
  }

Using only Javas own API:仅使用 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]);
}

Now, this code ist not the most efficient, but it relies only on standard java classes and is easy to understand.现在,这段代码不是最有效的,但它只依赖于标准的 java 类并且很容易理解。 It works for any number of String[] (even zero arrays).它适用于任意数量的 String[](甚至零数组)。

A type independent variation (UPDATED - thanks to Volley for instantiating T):类型无关的变体(更新 - 感谢 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()));
}

I found I had to deal with the case where the arrays can be null...我发现我必须处理数组可以为空的情况......

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;
}
String [] both = new ArrayList<String>(){{addAll(Arrays.asList(first)); addAll(Arrays.asList(second));}}.toArray(new String[0]);
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()]);
}

Every single answer is copying data and creating a new array.每个答案都是复制数据并创建一个新数组。 This is not strictly necessary and is definitely NOT what you want to do if your arrays are reasonably large.这不是绝对必要的,如果您的数组相当大,这绝对不是您想要做的。 Java creators already knew that array copies are wasteful and that is why they provided us System.arrayCopy() to do those outside Java when we have to. Java 创建者已经知道数组副本是浪费的,这就是为什么他们为我们提供 System.arrayCopy() 以在我们需要时在 Java 之外执行这些操作。

Instead of copying your data around, consider leaving it in place and draw from it where it lies.与其复制您的数据,不如考虑将其留在原处并从它所在的位置提取。 Copying data locations just because the programmer would like to organize them is not always sensible.仅仅因为程序员想要组织它们而复制数据位置并不总是明智的。

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

This is probably the only generic and type-safe way:这可能是唯一的通用和类型安全的方法:

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

And the usage is quite concise:用法非常简洁:

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

(requires static import) (需要静态导入)

Invalid array types are rejected:无效的数组类型被拒绝:

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

An easy, but inefficient, way to do this (generics not included): 一种简单但效率低下的方法(不包括泛型):

ArrayList baseArray = new ArrayList(Arrays.asList(array1));
baseArray.addAll(Arrays.asList(array2));
String concatenated[] = (String []) baseArray.toArray(new String[baseArray.size()]);

If you'd like to work with ArrayLists in the solution, you can try this:如果你想在解决方案中使用 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()]);
}

I think the best solution with generics would be:我认为泛型的最佳解决方案是:

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

Another one based on SilverTab's suggestion, but made to support x number of arguments and not require Java 6. It is also not generic, but I'm sure it could be made generic.另一个基于 SilverTab 的建议,但支持 x 个参数并且不需要 Java 6。它也不是通用的,但我确信它可以成为通用的。

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

You could replace String by a Type/Class of your liking你可以用你喜欢的类型/类替换​​字符串

Im sure this can be made shorter and better, but it works and im to lazy to sort it out further...我确定这可以做得更短更好,但它有效,我懒得进一步整理它......

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

Non Java 8 solution:非 Java 8 解决方案:

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

This one works only with int but the idea is generic这个只适用于 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];
}
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;

Yet another answer for algorithm lovers:算法爱好者的另一个答案:

public static String[] mergeArrays(String[] array1, String[] array2) {
    int totalSize = array1.length + array2.length; // Get total size
    String[] merged = new String[totalSize]; // Create new array
    // Loop over the total size
    for (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 array
            merged[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;

Usage:用法:

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

Result:结果:

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

You can try this method which concatenates multiple arrays:您可以尝试这种连接多个数组的方法:

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

In Java 8在 Java 8 中

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

concatenates a series of arrays compact, fast and type-safe with lambda使用 lambda 连接一系列紧凑、快速且类型安全的数组

@SafeVarargs
public 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 ) );
};

returns null when called without argument不带参数调用时返回null

eg.例如。 example with 3 arrays:具有 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]


"…probably the only generic and type-safe way" – adapted: “......可能是唯一的通用和类型安全的方式” ——改编:

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]

Just wanted to add, you can use System.arraycopy too:只是想补充一下,您也可以使用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("===");
    }
}

The easiest way i could find is as following :我能找到的最简单的方法如下:


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

I use next method to concatenate any number of arrays of the same type using java 8:我使用 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);
}

usage:用法:

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

or或者

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

I just discovered this question, sorry very late, and saw a lot of answers that were too far away, using certain libraries, using the feature of converting data from an array to a stream and back to an array and so on.刚刚发现这个问题,抱歉很晚了,看到很多答案太离谱了,使用某些库,使用将数据从数组转换为流再转换回数组的功能等等。 But, we can just use a simple loop and the problem is done但是,我们可以只使用一个简单的循环,问题就解决了

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

Thats it all, right?仅此而已,对吗? he didnt say he care about the order or anything.他没有说他关心订单或任何事情。 This should be the easiest way of it.这应该是最简单的方法了。

You can try this你可以试试这个

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

U can type cast your array !!!你可以输入你的数组!!!

Using Java Collections使用 Java Collections

Well, Java doesn't provide a helper method to concatenate arrays. However, since Java 5, the Collections utility class has introduced an addAll(Collection<? super T> c, T… elements) method.好吧,Java 没有提供连接 arrays 的辅助方法。但是,自 Java 5 以来,Collections 实用程序 class 引入了一个 addAll(Collection<? super T> 8811284.T65588 元素) 方法

We can create a List object, then call this method twice to add the two arrays to the list.我们可以创建一个List object,然后两次调用这个方法将两个arrays添加到列表中。 Finally, we convert the resulting List back to an array:最后,我们将结果列表转换回数组:

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

Test测试

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

I tested below code and worked ok我测试了下面的代码并且工作正常

Also I'm using library: org.apache.commons.lang.ArrayUtils我也在使用库: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]);
        }
    }
}

Regards问候

I see many generic answers with signatures such as public static T[] concat(T[] a, T[] b) {} but these only work on Object arrays, not on primitive arrays, as far as I can work out.我看到许多带有签名的通用答案,例如 public static T[] concat(T[] a, T[] b) {},但据我所知,这些答案仅适用于 Object arrays,不适用于原始 arrays。 The code below works both on Object and primitive arrays, making it more generic...下面的代码适用于 Object 和原始 arrays,使其更通用......

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

Look at this elegant solution (if you need other type than char, change it):看看这个优雅的解决方案(如果您需要除 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;
    }
}

You can concatenate a every count of arrays.您可以连接每个数组计数。

Should do the trick.应该做的伎俩。 This is assuming String[] first and String[] second这是假设 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()]);
    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];
}

This one works without knowledge of any other classes/libraries etc. It works for any data type.这个可以在不了解任何其他类/库等的情况下工作。它适用于任何数据类型。 Just replace String with anything like int , double or char .只需将String替换为intdoublechar It works quite efficiently.它的工作效率很高。

I have a simple method.我有一个简单的方法。 You don't want to waste your time to research complex java functions or libraries.您不想浪费时间研究复杂的 java 函数或库。 But the return type should be String.但是返回类型应该是String。

String[] f(String[] first, String[] second) {

    // Variable declaration part
    int 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;

}

So simple...很简单...

In Haskell you can do something like that [a, b, c] ++ [d, e] to get [a, b, c, d, e] .在 Haskell 中,您可以执行类似[a, b, c] ++ [d, e]来获得[a, b, c, d, e] These are Haskell lists concatenated but that'd very nice to see a similar operator in Java for arrays.这些是串联的 Haskell 列表,但很高兴在 Java 中看到类似的数组运算符。 Don't you think so ?你不这么认为吗? That's elegant, simple, generic and it's not that difficult to implement.这是优雅、简单、通用的,而且实现起来并不难。

If you want to, I suggest you to have a look at Alexander Hristov's work in his Hacking the OpenJDK compiler .如果你愿意,我建议你看看 Alexander Hristov 在他的Hacking the OpenJDK compiler 中的工作。 He explains how to modify javac source to create a new operator.他解释了如何修改 javac 源代码以创建新的运算符。 His example consists in defining a '**' operator where i ** j = Math.pow(i, j) .他的例子包括定义一个 '**' 运算符,其中i ** j = Math.pow(i, j) One could take that example to implement an operator that concatenates two arrays of same type.人们可以用这个例子来实现一个连接两个相同类型数组的运算符。

Once you do that, you are bound to your customized javac to compile your code but the generated bytecode will be understood by any JVM.一旦你这样做了,你就绑定到你定制的 javac 来编译你的代码,但生成的字节码将被任何 JVM 理解。

Of course, you can implement your own array concatenatation method at your source level, there are many examples on how to do it in the other answers !当然,您可以在源代码级别实现自己的数组连接方法,在其他答案中有很多关于如何执行此操作的示例!

There are so many useful operators that could be added, this one would be one of them.有很多有用的运算符可以添加,这就是其中之一。

Here is what worked for me:这是对我有用的:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM