Arrays.asList () vs Collections.singletonList ()


138

Apakah ada keuntungan (atau banyak perbedaan) untuk menggunakan Arrays.asList (sesuatu) daripada Collections.singletonList (sesuatu) untuk membuat daftar yang berisi satu item? Yang terakhir membuat daftar yang dikembalikan juga tidak berubah.


8
Anda bisa melempar jambu biji ImmutableList.of()dan Lists.newArrayList()campurannya juga.
biziclop

Selain itu, saya memiliki masalah dengan Collections.singletonList () yang menyebabkan masalah ketika metode mengembalikan Daftar yang kemudian dimodifikasi di bagian hilir.
Howard Grimberg

1
Java 10 memiliki daftar abadi yang benar: stackoverflow.com/a/52536126/1216775
akhil_mittal

Jawaban:


207

Collections.singletonList(something)tidak dapat diubah sedangkan representasi Arrays.asList(something)ukuran tetap Listdari Array tempat Daftar dan Array bergabung dalam heap.

Arrays.asList(something)memungkinkan perubahan non-struktural dibuat untuk itu, yang akan tercermin ke Daftar dan array yang digabungkan. Itu melempar UnsupportedOperationExceptionuntuk menambah, menghapus elemen meskipun Anda dapat mengatur elemen untuk indeks tertentu.

Setiap perubahan yang dilakukan pada Daftar yang dikembalikan oleh Collections.singletonList(something)akan menghasilkan UnsupportedOperationException.

Juga, kapasitas Daftar yang dikembalikan oleh Collections.singletonList(something)selalu 1 tidak seperti Arrays.asList(something)yang kapasitasnya akan sebesar array yang didukung.


63

Saya hanya ingin menambahkan bahwa singletonlist tidak didukung oleh array dan hanya memiliki referensi untuk satu item itu. Agaknya, itu akan memakan lebih sedikit memori dan dapat menjadi signifikan tergantung pada jumlah daftar yang ingin Anda buat.


Adakah tautan atau kode untuk mendukung titik efisiensi memori ini? Saya punya Arrays.asList (ONLY_ONE_OBJECT) ini ditulis jauh di seluruh basis kode dan ingin mengetahui apakah mengganti dengan Collections.singletonList () mengarah pada efisiensi memori?
Rahul Saini


13

Metode Arrays.asListmengembalikan daftar ukuran tetap yang didukung oleh array yang ditentukan. Metode mengembalikan contoh ArrayListyang merupakan kelas statis bersarang pribadi memperluas AbstractListdan tidak java.util.ArrayList. Kelas statis ini menyediakan implementasi beberapa metode, misalnya, set, indexOf, forEach, replaceAlldll. Tetapi ketika kita memanggilnya addtidak memiliki implementasi sendiri, melainkan metode dari AbstractListdipanggil yang melempar java.lang.UnsupportedOperationException.

The Collections.singletonListpengembalian sebuah daftar kekal yang hanya berisi objek tertentu dan itu adalah serializable juga.

Sebagai catatan, untuk daftar yang tidak dapat diubah, kami biasanya menggunakan Collections.unmodifiableListyang mengembalikan tampilan daftar yang tidak dapat dimodifikasi.

List<String> srcList = Arrays.asList("Apple", "Mango", "Banana");
var fruits = new ArrayList<>(srcList);
var unmodifiableList = Collections.unmodifiableList(fruits);     
fruits.set(0, "Apricot");
var modFruit = unmodifiableList.get(0);
System.out.println(modFruit); // prints Apricot

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 abadi sejati di Java 10 dan yang lebih baru. Ada dua cara untuk mendapatkan daftar yang benar-benar tidak dapat dimodifikasi :

  1. var unmodifiableList = List.copyOf(srcList);
  2. var unmodifiableList = srcList.stream().collect(Collectors.toUnmodifiableList()); Jika salah satu dari dua variabel ini digunakan, nilai akan tetap menjadi "Apple" dan bukan "Apricot".

Sebagai per doc dari Java 10 :

The List.ofdan List.copyOfmetode pabrik statis menyediakan cara yang nyaman untuk membuat daftar unmodifiable. Contoh instance yang dibuat oleh metode ini memiliki karakteristik berikut:

  1. Mereka tidak dapat dimodifikasi . Elemen tidak dapat ditambahkan, dihapus, atau diganti. Memanggil metode mutator pada Daftar akan selalu menyebabkan UnsupportedOperationExceptiondilemparkan. Namun, jika elemen-elemen yang terkandung itu sendiri bisa berubah-ubah, ini dapat menyebabkan konten Daftar tampaknya berubah.
  2. Mereka melarang elemen nol. Upaya untuk membuatnya dengan elemen nol menghasilkan NullPointerException.
  3. Mereka dapat serial jika semua elemen serial.
  4. Urutan elemen dalam daftar sama dengan urutan argumen yang disediakan, atau elemen dalam array yang disediakan.
  5. Mereka adalah value-based. Penelepon tidak boleh membuat asumsi tentang identitas contoh yang dikembalikan. Pabrik bebas membuat instance baru atau menggunakan kembali yang sudah ada. Oleh karena itu, operasi sensitif-identitas pada instance ini (referensi kesetaraan (==), kode hash identitas, dan sinkronisasi) tidak dapat diandalkan dan harus dihindari.
  6. Mereka serial seperti yang ditentukan pada halaman Formulir Serialized .
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.