Как я могу объединить два массива в Java?

Это не отвечает на ваш вопрос напрямую, но я хотел бросить пару вещей:

Обычно я считаю контрпродуктивным отдельный сгенерированный код. Мне всегда нравится, как правило, следовать правилу «один класс за файл», но здесь я делаю исключение, потому что часто имею дело с очень большими схемами. Даже в своем собственном каталоге, я не хочу, чтобы разделить десятки (до сотен) файлов, когда я создаю новую версию кода. Мне очень удобно иметь весь сгенерированный код, который может быть размытым в одном файле.

Теперь, чтобы предложить возможное решение - Resharper имеет возможность вытащить все классы из файл и поместить их в свои собственные файлы. Если вы щелкните правой кнопкой мыши файл в проводнике решений, вы можете сказать Refactor → Переместить типы в соответствующие файлы ... . Конечно, это не так удобно, как просто генерировать его таким образом, но я не знаю инструмента, который это сделает.

1259
задан 6 revs, 4 users 73% 22 December 2018 в 15:35
поделиться

41 ответ

Еще один ответ для любителей алгоритма:

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;

Использование:

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]
-1
ответ дан c-chavez 22 December 2018 в 15:35
поделиться

Вот моя слегка улучшенная версия concatAll Йоахима Зауэра. Он может работать на Java 5 или 6, используя Java 6 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" 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
ответ дан candrews 22 December 2018 в 15:35
поделиться

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

Как насчет:

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
ответ дан clément francomme 22 December 2018 в 15:35
поделиться

Простой вариант, позволяющий объединять более одного массива:

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
ответ дан 2 revs, 2 users 78% 22 December 2018 в 15:35
поделиться

Каждый ответ копирует данные и создает новый массив. Это не является строго необходимым и определенно НЕ то, что вы хотите делать, если ваши массивы достаточно велики. Создатели 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
}
2
ответ дан 2 revs 22 December 2018 в 15:35
поделиться

Это работает, но вам нужно вставить свою собственную проверку ошибок.

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

Это, вероятно, не самый эффективный, но он не зависит ни от чего, кроме собственного API Java.

6
ответ дан 2 revs, 2 users 72% 22 December 2018 в 15:35
поделиться

Только Используя 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]);
}

Теперь, этот код ist не самое эффективное, но это полагается только на стандартные классы Java и легко понять. Это работает на любое количество Строки [] (даже нулевые массивы).

3
ответ дан Kiwi 22 December 2018 в 15:35
поделиться
  • 1
    @Timo можно ли указать, где точно в документе он говорит это? – 2cupsOfTech 30 November 2012 в 16:10

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;
}
468
ответ дан 19 December 2019 в 20:15
поделиться

Простой, но неэффективный способ сделать это (непатентованные средства не включены):

ArrayList baseArray = new ArrayList(Arrays.asList(array1));
baseArray.addAll(Arrays.asList(array2));
String concatenated[] = (String []) baseArray.toArray(new String[baseArray.size()]);
3
ответ дан 19 December 2019 в 20:15
поделиться

Вариант, не зависящий от типа (ОБНОВЛЕНО - спасибо 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
ответ дан 19 December 2019 в 20:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: