How can I concatenate two arrays in Java?

I need to concatenate two String arrays in Java.

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

What is the easiest way to do this?

60 AnswersDefault Order

Antti Sykäri

talk is cheap , show me the code

I found a one-line solution from the good old Apache Commons Lang library.
ArrayUtils.addAll(T[], T...)

Code:

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

edited on Fri Nov 24 11:43:45 UTC 2017

  • 861
  • 21 comments
  • wrap

jeannicolas

talk is cheap , show me the code

Here's a method that will concatenate 2 arrays of type Foo (replace Foo in the code with your classname in question).

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

(source: Sun Forum )

Here is a version that works with 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;
}

Note like all generics it will not work with primitives but with Objects.

edited on Tue Dec 05 21:43:45 UTC 2017

  • 693
  • 21 comments
  • wrap

Joachim Sauer

talk is cheap , show me the code

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

Both versions avoid creating any intermediary List objects and use System.arraycopy() to ensure that copying large arrays is as fast as possible.

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:

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

edited on Fri Dec 01 14:12:45 UTC 2017

  • 426
  • 21 comments
  • wrap

Vitalii Fedorenko

talk is cheap , show me the code

One-liner in Java 8:

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

Or:

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

edited on Wed Dec 06 09:37:45 UTC 2017

  • 287
  • 21 comments
  • wrap

KARASZI István

talk is cheap , show me the code

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)

edited on Tue Dec 05 02:33:45 UTC 2017

  • 151
  • 21 comments
  • wrap

Fabian Steeg

talk is cheap , show me the code

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

edited on Mon Dec 04 16:25:45 UTC 2017

  • 50
  • 21 comments
  • wrap

francois

talk is cheap , show me the code

A solution 100% old java and without System.arraycopy (not available in GWT client for example):

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

edited on Thu Nov 30 22:29:45 UTC 2017

  • 33
  • 21 comments
  • wrap

volley

talk is cheap , show me the code

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

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

(In either case, array re-usage behaviour shall be clearly JavaDoced!)

edited on Sat Dec 02 10:54:45 UTC 2017

  • 29
  • 21 comments
  • wrap

Apocalisp

talk is cheap , show me the code

The Functional Java library has an array wrapper class that equips arrays with handy methods like concatenation.

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

edited on Wed Dec 13 09:11:45 UTC 2017

  • 24
  • 21 comments
  • wrap

volley

talk is cheap , show me the code

Here's an adaptation of silvertab's solution, with generics retrofitted:

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. Not only does it eliminate the warning; it's also shorter, more efficient and easier to read!

edited on Thu Nov 30 20:17:45 UTC 2017

  • 17
  • 21 comments
  • wrap

Vaseph

talk is cheap , show me the code

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

edited on Mon Dec 04 16:40:45 UTC 2017

  • 15
  • 21 comments
  • wrap

nick-s

talk is cheap , show me the code

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

both.toArray();

edited on Sat Nov 25 23:56:45 UTC 2017

  • 12
  • 21 comments
  • wrap

Raj S. Rusia

talk is cheap , show me the code

If you use this way so you no need to import any third party class.

If you want concatenate 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

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.

edited on Fri Dec 01 06:48:45 UTC 2017

  • 11
  • 21 comments
  • wrap

Zalumon

talk is cheap , show me the code

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

edited on Mon Dec 04 17:22:45 UTC 2017

  • 10
  • 21 comments
  • wrap

Paul

talk is cheap , show me the code

You could try converting it into a Arraylist and use the addAll method then convert back to an array.

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

edited on Sun Dec 10 15:45:45 UTC 2017

  • 10
  • 21 comments
  • wrap

hpgisler

talk is cheap , show me the code

Here a possible implementation in working code of the pseudo code solution written by 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

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:

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

edited on Mon Dec 04 11:42:45 UTC 2017

  • 7
  • 21 comments
  • wrap

doles

talk is cheap , show me the code

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

edited on Wed Nov 29 08:19:45 UTC 2017

  • 6
  • 21 comments
  • wrap

Oritm

talk is cheap , show me the code

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

edited on Thu Nov 23 19:20:45 UTC 2017

  • 5
  • 21 comments
  • wrap

Ephraim

talk is cheap , show me the code

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). As long as arr1 and arr2 are of the same type, this will give you another array of the same type containing both arrays.

edited on Wed Dec 06 15:37:45 UTC 2017

  • 5
  • 21 comments
  • wrap

Kiwi

talk is cheap , show me the code

Using only Javas own 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. It works for any number of String[] (even zero arrays).

edited on Wed Dec 06 13:37:46 UTC 2017

  • 4
  • 21 comments
  • wrap

candrews

talk is cheap , show me the code

Here's my slightly improved version of Joachim Sauer's concatAll. It can work on Java 5 or 6, using Java 6's System.arraycopy if it's available at runtime. 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.

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

edited on Sun Dec 03 20:41:46 UTC 2017

  • 4
  • 21 comments
  • wrap

Earth Engine

talk is cheap , show me the code

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. Some other answers uses ArrayList, and that's fine. 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. However I think this one has its own beauty.

edited on Sun Dec 03 11:48:46 UTC 2017

  • 4
  • 21 comments
  • wrap

clément francomme

talk is cheap , show me the code

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

edited on Sun Nov 26 14:31:46 UTC 2017

  • 4
  • 21 comments
  • wrap

Damo

talk is cheap , show me the code

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

edited on Sun Dec 10 01:33:46 UTC 2017

  • 4
  • 21 comments
  • wrap

glue

talk is cheap , show me the code

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.

edited on Sun Nov 26 07:57:46 UTC 2017

  • 4
  • 21 comments
  • wrap

Frimousse

talk is cheap , show me the code

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

edited on Sun Dec 03 01:47:46 UTC 2017

  • 3
  • 21 comments
  • wrap

Damo

talk is cheap , show me the code

A type independent variation (UPDATED - thanks to Volley for instantiating 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()));
}

edited on Sat Dec 09 06:58:46 UTC 2017

  • 3
  • 21 comments
  • wrap

Bob Cross

talk is cheap , show me the code

If you'd like to work with ArrayLists in the solution, you can try this:

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

edited on Wed Nov 29 05:45:46 UTC 2017

  • 2
  • 21 comments
  • wrap

MetroidFan2002

talk is cheap , show me the code

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

edited on Tue Dec 12 07:39:46 UTC 2017

  • 2
  • 21 comments
  • wrap

Sujay

talk is cheap , show me the code

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

edited on Fri Nov 24 17:39:46 UTC 2017

  • 2
  • 21 comments
  • wrap