首页 文章

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

提问于
浏览
1178

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

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

最简单的方法是什么?

30 回答

  • 7

    这是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;
    }
    
  • 31

    Functional Java库有一个数组包装类,它为数组提供了连接等方便的方法 .

    import static fj.data.Array.array;
    

    ...然后

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

    要取出展开的阵列,请致电

    String[] s = both.array();
    
  • 4

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

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

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

    我们也可以用这种方式 .

  • 3

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

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

    这是对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;
    }
    

    注意:有关Java 6解决方案,请参阅Joachim's answer . 它不仅消除了警告;它也更短,更高效,更容易阅读!

  • 6

    允许连接多个阵列的简单变体:

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

    怎么样简单

    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 属于同一类型,这将为您提供另一个包含两个数组的相同类型的数组 .

  • 3

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

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

    怎么样 :

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

    您可以将这两个数组附加到两行代码中 .

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

    这是一种快速有效的解决方案,适用于原始类型,并且所涉及的两种方法都是重载的 .

    您应该避免涉及ArrayLists,流等的解决方案,因为这些解决方案需要分配临时内存而没有用处 .

    你应该避免 for 循环,因为这些循环效率不高 . 内置方法使用极快的块复制功能 .

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

    另一种思考问题的方法 . 要连接两个或多个数组,必须要列出每个数组的所有元素,然后构建一个新数组 . 这听起来像创建 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 的解决方案 . 不过我觉得这个有自己的美 .

  • 12

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

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

    这是我对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;
      }
    
  • 27

    我从优秀的旧Apache Commons Lang库中找到了一个单行解决方案 .
    ArrayUtils.addAll(T[], T...)

    码:

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

    解决方案 100% old javawithout 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;
    }
    
  • 4

    或者与心爱的Guava

    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)

  • 3

    仅使用Javas自己的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 [](甚至是零数组) .

  • 5

    这有效,但您需要插入自己的错误检查 .

    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以外的任何东西 .

  • 37

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

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

    这里是由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> {
    
       @Override
       public Integer[] build(int size) {
          return new Integer[size];
       }
    }
    

    最后是申请/测试:

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

    使用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()]);
    }
    
  • 3

    我最近在过度记忆旋转方面遇到了问题 . 如果已知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;
    }
    

    (在任何一种情况下,数组重用行为都应该是明确的JavaDoced!)

  • 731

    请原谅我在这个已经很久的列表中添加了另一个版本 . 我看了每个答案,然后决定我真的想要签名中只有一个参数的版本 . 我还添加了一些参数检查,以便在意外输入的情况下通过合理的信息从早期故障中受益 .

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

    一个独立的类型变体(更新 - 感谢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()));
    }
    
  • 26
    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;
    }
    
  • 17

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

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

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

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

相关问题