Konversi array ke daftar di Jawa

1028

Bagaimana cara mengubah array ke daftar di Jawa?

Saya menggunakan Arrays.asList()tetapi perilaku (dan tanda tangan) entah bagaimana berubah dari Java SE 1.4.2 (sekarang dalam arsip) ke 8 dan sebagian besar cuplikan yang saya temukan di web menggunakan perilaku 1.4.2.

Sebagai contoh:

int[] spam = new int[] { 1, 2, 3 };
Arrays.asList(spam)
  • pada 1.4.2 mengembalikan daftar yang berisi elemen 1, 2, 3
  • pada 1.5.0+ mengembalikan daftar yang berisi spam array

Dalam banyak kasus seharusnya mudah untuk dideteksi, tetapi kadang-kadang bisa tidak diketahui:

Assert.assertTrue(Arrays.asList(spam).indexOf(4) == -1);
Alexandru
sumber
20
Saya pikir contoh Anda rusak Arrays.asList(new int[] { 1, 2, 3 }):; pasti tidak mengkompilasi di Jawa 1.4.2, karena seorang int[]yang tidak seorang Object[].
Joachim Sauer
1
Oh, kamu mungkin benar. Saya tidak memiliki kompiler Java 1.4.2 untuk menguji contoh saya sebelum memposting. Sekarang, setelah komentar Anda dan jawaban Joe, semuanya jauh lebih masuk akal.
Alexandru
1
Saya pikir Autoboxing akan mencakup konversi dari primitif ke kelas Integer wrapper. Anda dapat membuat gips sendiri terlebih dahulu dan kemudian kode di atas untuk Arrays.asListbekerja.
Horse Voice
2
Java 8's Stream.boxed () akan menangani autoboxing dan dapat digunakan untuk ini. Lihat jawaban saya di bawah ini .
Ibrahim Arief
Solusi Java 8: stackoverflow.com/questions/2607289/…
akhil_mittal

Jawaban:

1431

Dalam contoh Anda, itu karena Anda tidak dapat memiliki Daftar tipe primitif. Dengan kata lain, List<int>itu tidak mungkin.

Namun, Anda dapat List<Integer>menggunakan Integerkelas yang membungkus intprimitif. Konversi array Anda menjadi Listdengan Arrays.asListmetode utilitas.

Integer[] spam = new Integer[] { 1, 2, 3 };
List<Integer> list = Arrays.asList(spam);

Lihat kode ini berjalan langsung di IdeOne.com .

Joe Daley
sumber
112
Atau bahkan lebih sederhana: Arrays.asList (1, 2, 3);
Kong
45
Bagaimana ia tahu untuk tidak membuat List<Integer[]>?
Thomas Ahle
25
Gagal di Java 5+.
djechlin
6
@ThomasAhle Ini tidak membuat Daftar <Integer []> itu membuat objek Daftar <Integer>. Dan jika Anda ingin mengetik aman Anda menulis: Array. <Integer> asList (spam);
user1712376
6
@ThomasAhle Itu pertanyaan yang bagus. Tebakan itu hanya aturan di kompiler java. Sebagai contoh, kode berikut mengembalikan Daftar <Integer []> Integer[] integerArray1 = { 1 }; Integer[] integerArray2 = { 2 }; List<Integer[]> integerArrays = Arrays.asList(integerArray1, integerArray2);
Simon
167

Di Java 8, Anda dapat menggunakan stream:

int[] spam = new int[] { 1, 2, 3 };
Arrays.stream(spam)
      .boxed()
      .collect(Collectors.toList());
Ibrahim Arief
sumber
Ini bagus, tetapi tidak akan berhasil boolean[]. Saya kira itu karena mudah membuatnya Boolean[]. Itu mungkin solusi yang lebih baik. Bagaimanapun, ini adalah kekhasan yang menarik.
GlenPeterson
138

Berbicara tentang cara konversi, itu tergantung pada mengapa Anda memerlukannya List. Jika Anda membutuhkannya hanya untuk membaca data. Oke, ini dia:

Integer[] values = { 1, 3, 7 };
List<Integer> list = Arrays.asList(values);

Tetapi jika Anda melakukan sesuatu seperti ini:

list.add(1);

kamu dapatkan java.lang.UnsupportedOperationException. Jadi untuk beberapa kasus Anda bahkan memerlukan ini:

Integer[] values = { 1, 3, 7 };
List<Integer> list = new ArrayList<Integer>(Arrays.asList(values));

Pendekatan pertama sebenarnya tidak mengubah array tetapi 'mewakili' seperti List. Tetapi array berada di bawah tenda dengan semua propertinya seperti jumlah elemen yang tetap. Harap perhatikan bahwa Anda perlu menentukan tipe saat membuat ArrayList.

Roman Nikitchenko
sumber
1
"kekekalan" membuatku bingung sejenak. Anda jelas dapat mengubah nilai-nilai array. Anda tidak dapat mengubah ukurannya.
Tim Pohlmann
125

Masalahnya adalah bahwa Arrays.asList()vararg diperkenalkan di Java5 dan sayangnya, kelebihan beban dengan versi vararg juga. Jadi Arrays.asList(spam)dipahami oleh kompiler Java5 sebagai parameter vararg dari array int.

Masalah ini dijelaskan secara lebih terperinci dalam Effective Java 2nd Ed., Bab 7, Item 42.

Péter Török
sumber
4
Saya mengerti apa yang terjadi, tetapi bukan mengapa itu tidak didokumentasikan. Saya mencari solusi alternatif tanpa menerapkan kembali roda.
Alexandru
2
@UsmanIsmail Pada Java 8, kita dapat menggunakan stream untuk konversi ini. Lihat jawaban saya di bawah ini .
Ibrahim Arief
109

Tampaknya sedikit terlambat tetapi ini adalah dua sen saya. Kita tidak dapat memiliki List<int>sebagai intadalah tipe primitif sehingga kita hanya dapat memiliki List<Integer>.

Java 8 (int array)

int[] ints = new int[] {1,2,3,4,5};
List<Integer> list11 =Arrays.stream(ints).boxed().collect(Collectors.toList()); 

Java 8 dan yang lebih baru (array Integer)

Integer[] integers = new Integer[] {1,2,3,4,5};
List<Integer> list21 =  Arrays.asList(integers); // returns a fixed-size list backed by the specified array.
List<Integer> list22 = new ArrayList<>(Arrays.asList(integers)); // good
List<Integer> list23 = Arrays.stream(integers).collect(Collectors.toList()); //Java 8 only

Perlu ArrayList dan bukan Daftar?

Jika kita menginginkan implementasi spesifik dari Listeg ArrayListmaka kita dapat menggunakan toCollectionsebagai:

ArrayList<Integer> list24 = Arrays.stream(integers)
                          .collect(Collectors.toCollection(ArrayList::new));

Mengapa list21tidak dapat dimodifikasi secara struktural?

Ketika kita menggunakan Arrays.asListukuran daftar yang dikembalikan adalah tetap karena daftar yang dikembalikan bukan java.util.ArrayList, tetapi kelas statis pribadi yang didefinisikan di dalamnya java.util.Arrays. Jadi jika kita menambah atau menghapus elemen dari daftar yang dikembalikan, sebuah UnsupportedOperationExceptionakan dilempar. Jadi kita harus pergi list22ketika kita ingin mengubah daftar. Jika kita memiliki Java8 maka kita juga bisa menggunakannya list23.

Agar jelas list21dapat dimodifikasi dalam arti bahwa kita dapat memanggil list21.set(index,element)tetapi daftar ini mungkin tidak dimodifikasi secara struktural yaitu tidak dapat menambah atau menghapus elemen dari daftar. Anda juga dapat memeriksa pertanyaan ini .


Jika kita menginginkan daftar yang tidak dapat diubah maka kita dapat membungkusnya sebagai:

List<Integer> list 22 = Collections.unmodifiableList(Arrays.asList(integers));

Hal lain yang perlu diperhatikan adalah bahwa metode ini Collections.unmodifiableListmengembalikan tampilan daftar yang ditentukan yang tidak dapat dimodifikasi. Koleksi tampilan yang tidak dapat dimodifikasi adalah koleksi yang tidak dapat dimodifikasi dan juga merupakan tampilan ke koleksi dukungan. Perhatikan bahwa perubahan pada koleksi dukungan mungkin masih dimungkinkan, dan jika terjadi, mereka dapat dilihat melalui tampilan yang tidak dapat dimodifikasi.

Kita dapat memiliki daftar yang benar-benar abadi di Jawa 9 dan 10.

Daftar yang benar-benar tidak dapat berubah

Java 9:

String[] objects = {"Apple", "Ball", "Cat"};
List<String> objectList = List.of(objects);

Java 10 (Daftar Benar-Benar Tidak Berubah) dalam dua cara:

  1. List.copyOf(Arrays.asList(integers))
  2. Arrays.stream(integers).collect(Collectors.toUnmodifiableList());

Periksa juga jawaban saya ini untuk informasi lebih lanjut.

akhil_mittal
sumber
@ BasilBourque yang saya maksud tidak dapat mengubah struktur daftar dengan penambahan / penghapusan tetapi dapat mengubah elemen.
akhil_mittal
Memang, saya mencoba beberapa kode dan mengkonfirmasi bahwa panggilan List::add& List::removegagal dengan daftar dikembalikan oleh Arrays.asList. JavaDoc untuk metode itu ditulis dengan buruk dan tidak jelas dalam hal ini. Pada bacaan ketiga saya, saya kira kalimat "ukuran tetap" di sana dimaksudkan untuk mengatakan seseorang tidak dapat menambah atau menghapus elemen.
Basil Bourque
12

Bahkan lebih pendek:

List<Integer> list = Arrays.asList(1, 2, 3, 4);
Vitaliy Sokolov
sumber
11

Baru-baru ini saya harus mengubah array ke Daftar. Kemudian program menyaring daftar yang berusaha menghapus data. Saat Anda menggunakan fungsi Arrays.asList (array), Anda membuat koleksi ukuran tetap: Anda tidak bisa menambah atau menghapus. Entri ini menjelaskan masalah lebih baik daripada yang saya bisa: Mengapa saya mendapatkan UnsupportedOperationException ketika mencoba menghapus elemen dari Daftar? .

Pada akhirnya, saya harus melakukan konversi "manual":

    List<ListItem> items = new ArrayList<ListItem>();
    for (ListItem item: itemsArray) {
        items.add(item);
    }

Saya kira saya bisa menambahkan konversi dari array ke daftar menggunakan operasi List.addAll (item).

Steve Gelman
sumber
11
new ArrayList<ListItem>(Arrays.asList(itemsArray))akan sama
Marco13
1
@ BradyZhu: Diberikan jawaban di atas tidak menyelesaikan masalah saya dengan array ukuran tetap, tetapi Anda pada dasarnya mengatakan RTFM di sini, yang selalu merupakan bentuk yang buruk. Tolong jelaskan apa yang salah dengan jawabannya atau tidak perlu berkomentar.
Steve Gelman
2
Alat inspeksi dapat menunjukkan peringatan di sini, dan Anda telah menyebutkan alasannya. Tidak perlu menyalin elemen secara manual, gunakan Collections.addAll(items, itemsArray)saja.
Darek Kay
Tekan saja pengecualian ini. Saya khawatir jawaban Marco13 harus menjadi jawaban yang benar. Saya mungkin harus menggunakan kode sepanjang tahun untuk memperbaiki semua pengecualian "asList".
7

Menggunakan Array

Ini adalah cara paling sederhana untuk mengonversi array menjadi List. Namun, jika Anda mencoba menambahkan elemen baru atau menghapus elemen yang ada dari daftar, sebuah UnsupportedOperationExceptionakan dilempar.

Integer[] existingArray = {1, 2, 3};
List<Integer> list1 = Arrays.asList(existingArray);
List<Integer> list2 = Arrays.asList(1, 2, 3);

// WARNING:
list2.add(1);     // Unsupported operation!
list2.remove(1);  // Unsupported operation!

Menggunakan ArrayList atau Implementasi Daftar Lainnya

Anda bisa menggunakan forloop untuk menambahkan semua elemen array ke dalam Listimplementasi, misalnya ArrayList:

List<Integer> list = new ArrayList<>();
for (int i : new int[]{1, 2, 3}) {
  list.add(i);
}

Menggunakan Stream API di Java 8

Anda bisa mengubah array menjadi stream, lalu kumpulkan stream menggunakan kolektor berbeda: Kolektor default di Java 8 menggunakan di ArrayListbelakang layar, tetapi Anda juga bisa memaksakan implementasi yang Anda inginkan.

List<Integer> list1, list2, list3;
list1 = Stream.of(1, 2, 3).collect(Collectors.toList());
list2 = Stream.of(1, 2, 3).collect(Collectors.toCollection(ArrayList::new));
list3 = Stream.of(1, 2, 3).collect(Collectors.toCollection(LinkedList::new));

Lihat juga:

Mincong Huang
sumber
6

Solusi lain jika Anda menggunakan apache commons-lang:

int[] spam = new int[] { 1, 2, 3 };
Arrays.asList(ArrayUtils.toObject(spam));

Di mana ArrayUtils.toObject dikonversi int[]menjadiInteger[]

Alaster
sumber
5

Anda harus memasukkan ke dalam array

Arrays.asList((Object[]) array)
Giancarlo Frison
sumber
3
java: jenis yang tidak kompatibel: int [] tidak dapat dikonversi ke java.lang.Object []
dVaffection
@dVaffection Lalu dilemparkan ke int []. Bagian penting adalah untuk dilemparkan ke sebuah array.
Nebril
5

Satu-liner:

List<Integer> list = Arrays.asList(new Integer[] {1, 2, 3, 4});
Bhushan
sumber
5

Di Java 9 Anda memiliki solusi yang lebih elegan menggunakan daftar abadi melalui metode pabrik kenyamanan baru List.of:

List<String> immutableList = List.of("one","two","three");

(Tanpa malu-malu disalin dari sini )

Pierluigi Vernetto
sumber
FYI, untuk mempelajari beberapa detail teknis di balik ini, lihat JEP 269: Convenience Factory Methods for Collections dan ceramah oleh Stuart Marks , penulis utama.
Basil Bourque
5

Jika Anda menargetkan Java 8 (atau lebih baru), Anda dapat mencoba ini:

int[] numbers = new int[] {1, 2, 3, 4};
List<Integer> integers = Arrays.stream(numbers)
                        .boxed().collect(Collectors.<Integer>toList());

CATATAN:

Perhatikan Collectors.<Integer>toList(), metode umum ini membantu Anda menghindari kesalahan "Ketik ketidakcocokan: tidak dapat dikonversi dari List<Object>ke List<Integer>".

nybon
sumber
4
  1. Menggunakan jambu biji:

    Integer[] array = { 1, 2, 3};
    List<Integer> list = Lists.newArrayList(sourceArray);
  2. Menggunakan Koleksi Apache Commons:

    Integer[] array = { 1, 2, 3};
    List<Integer> list = new ArrayList<>(6);
    CollectionUtils.addAll(list, array);
Danail Tsvetanov
sumber
3

Jika ini membantu: Saya memiliki masalah yang sama dan hanya menulis fungsi generik yang mengambil array dan mengembalikan ArrayList dari tipe yang sama dengan konten yang sama:

public static <T> ArrayList<T> ArrayToArrayList(T[] array) {
    ArrayList<T> list = new ArrayList<T>();
    for(T elmt : array) list.add(elmt);
    return list;
}
kleines filmröllchen
sumber
Bagaimana jika itu tidak membantu? Lalu apa yang kamu lakukan ?? ... jk :)
Sᴀᴍ Onᴇᴌᴀ
2

Array yang Diberikan:

    int[] givenArray = {2,2,3,3,4,5};

Mengubah array integer ke Daftar Integer

Satu cara: boxed () -> mengembalikan IntStream

    List<Integer> givenIntArray1 = Arrays.stream(givenArray)
                                  .boxed()
                                  .collect(Collectors.toList());

Cara Kedua: memetakan setiap elemen aliran ke Integer dan kemudian mengumpulkan

CATATAN: Menggunakan mapToObj, Anda dapat menyamarkan setiap elemen int ke dalam string stream, char stream, dll dengan casing i to (char) i

    List<Integer> givenIntArray2 = Arrays.stream(givenArray)
                                         .mapToObj(i->i)
                                         .collect(Collectors.toList());

Mengubah Satu Jenis Array ke Jenis Lain Contoh:

List<Character> givenIntArray2 = Arrays.stream(givenArray)
                                             .mapToObj(i->(char)i)
                                             .collect(Collectors.toList());
Arpan Saini
sumber
1

Jadi itu tergantung pada versi Java yang Anda coba-

Java 7

 Arrays.asList(1, 2, 3);

ATAU

       final String arr[] = new String[] { "G", "E", "E", "K" };
       final List<String> initialList = new ArrayList<String>() {{
           add("C");
           add("O");
           add("D");
           add("I");
           add("N");
       }};

       // Elements of the array are appended at the end
       Collections.addAll(initialList, arr);

ATAU

Integer[] arr = new Integer[] { 1, 2, 3 };
Arrays.asList(arr);

Di Jawa 8

int[] num = new int[] {1, 2, 3};
List<Integer> list = Arrays.stream(num)
                        .boxed().collect(Collectors.<Integer>toList())

Referensi - http://www.codingeek.com/java/how-to-convert-array-to-list-in-java/

Hitesh Garg
sumber
1

Bisakah Anda meningkatkan jawaban ini karena ini adalah apa yang saya gunakan tetapi saya tidak 100% jelas. Ini berfungsi dengan baik tetapi intelliJ menambahkan WeatherStation baru [0]. Mengapa 0?

    public WeatherStation[] removeElementAtIndex(WeatherStation[] array, int index)
    {
        List<WeatherStation> list = new ArrayList<WeatherStation>(Arrays.asList(array));
        list.remove(index);
        return list.toArray(new WeatherStation[0]);
    }

DevilCode
sumber
Mengapa kami harus meningkatkan pertanyaan Anda ? Entah Anda tahu jawabannya, atau tidak. Tentu saja Anda harus memberikan jawaban yang benar-benar membantu orang lain, bukan jawaban yang membingungkan daripada membantu.
HimBromBeere
-2

menggunakan dua baris kode untuk mengkonversi array ke daftar jika Anda menggunakannya dalam nilai integer Anda harus menggunakan tipe autoboxing untuk tipe data primitif

  Integer [] arr={1,2};
  Arrays.asList(arr);
Yousef
sumber