Pertanyaan Bagaimana saya bisa menggabungkan dua larik di Java?


Saya perlu menggabungkan dua susunan String di Java.

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

Apa cara termudah untuk melakukan ini?


1134


asal


Jawaban:


Saya menemukan solusi satu baris dari perpustakaan Apache Commons Lang yang baik.
  ArrayUtils.addAll(T[], T...)

Kode:

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

922



Berikut ini metode sederhana yang akan menggabungkan dua larik dan mengembalikan hasilnya:

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

Catatan seperti itu tidak akan bekerja dengan primitif, hanya dengan jenis objek.

Versi yang sedikit lebih rumit berikut bekerja dengan objek dan array primitif. Ia melakukan ini dengan menggunakan T dari pada T[] sebagai tipe argumen.

Ini juga memungkinkan untuk menggabungkan array dari dua tipe yang berbeda dengan memilih tipe yang paling umum sebagai tipe komponen dari hasil.

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

Berikut ini contohnya:

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

721



Ini mungkin untuk menulis versi yang sepenuhnya generik yang bahkan dapat diperluas untuk menggabungkan sejumlah larik. Versi ini membutuhkan Java 6, seperti yang mereka gunakan Arrays.copyOf()

Kedua versi menghindari pembuatan perantara apa pun List benda dan penggunaan System.arraycopy() untuk memastikan bahwa menyalin array besar secepat mungkin.

Untuk dua larik, terlihat seperti ini:

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

Dan untuk sejumlah acak array (> = 1) terlihat seperti ini:

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

440



Satu-liner di Java 8:

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

Atau:

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

326



Atau dengan yang dicintai Jambu biji:

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

Juga, ada versi untuk array primitif:

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

168



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

53



Sebuah solusi Java 100% lama dan tanpa  System.arraycopy (tidak tersedia di klien GWT misalnya):

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

36