Как я могу объединить два массива в Java? - PullRequest
1243 голосов
/ 17 сентября 2008

Мне нужно объединить два String массива в Java.

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

Какой самый простой способ сделать это?

Ответы [ 58 ]

5 голосов
/ 12 октября 2011

Как насчет просто

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). Пока arr1 и arr2 имеют одинаковый тип, это даст вам другой массив того же типа, содержащий оба массива.

5 голосов
/ 11 июня 2011

Это преобразованная функция для массива 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;
}
5 голосов
/ 27 октября 2018

Это должен быть однострочник.

public String [] concatenate (final String array1[], final String array2[])
{
    return Stream.concat(Stream.of(array1), Stream.of(array2)).toArray(String[]::new);
}
4 голосов
/ 12 февраля 2015

Как насчет:

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()]);
}
4 голосов
/ 27 февраля 2013

Еще один способ задуматься над вопросом. Чтобы объединить два или более массивов, нужно составить список всех элементов каждого массива, а затем построить новый массив. Это звучит как создать 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. Однако я думаю, что у этого есть своя собственная красота.

4 голосов
/ 09 июня 2011

Вот моя слегка улучшенная версия concatAll Йоахима Зауэра. Он может работать на Java 5 или 6, используя Java 6 System.arraycopy, если он доступен во время выполнения. Этот метод (IMHO) идеально подходит для Android, так как он работает на Android <9 (у которого нет System.arraycopy), но будет использовать более быстрый метод, если это возможно. </p>

  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;
  }
4 голосов
/ 18 июня 2009

Простой вариант, допускающий объединение нескольких массивов:

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()]);
}
3 голосов
/ 18 июня 2009

Вариант, независимый от типа (ОБНОВЛЕНО - спасибо 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()));
}
3 голосов
/ 07 ноября 2018

Общая статическая версия, в которой используется высокопроизводительная 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;
}
3 голосов
/ 17 сентября 2008

Использование только собственного API Javas:


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 [] (даже нулевых массивов).

...