Lihat JavaDocs dan pembicaraan ini oleh Stuart Marks (atau versi sebelumnya).
Saya akan menggunakan yang berikut ini untuk contoh kode:
List<Integer> listOf = List.of(...);
List<Integer> asList = Arrays.asList(...);
List<Integer> unmodif = Collections.unmodifiableList(asList);
Kekekalan struktural (Atau: tidak dapat dimodifikasi)
Setiap upaya untuk mengubah strukturList.of
akan menghasilkan file UnsupportedOperationException
. Itu termasuk operasi seperti menambah , mengatur , dan menghapus . Namun, Anda dapat mengubah konten objek dalam daftar (jika objek tersebut tidak dapat diubah), sehingga daftar tersebut tidak "sepenuhnya tidak dapat diubah".
Ini adalah nasib yang sama untuk daftar yang tidak dapat dimodifikasi yang dibuat dengan Collections.unmodifiableList
. Hanya daftar ini yang merupakan tampilan dari daftar asli, sehingga dapat berubah jika Anda mengubah daftar aslinya.
Arrays.asList
tidak sepenuhnya tidak berubah, tidak ada batasan set
.
listOf.set(1, "a"); // UnsupportedOperationException
unmodif.set(1, "a"); // UnsupportedOperationException
asList.set(1, "a"); // modified unmodif! unmodif is not truly unmodifiable
Demikian pula, mengubah larik pendukung (jika Anda menahannya) akan mengubah daftar.
Kekekalan struktural hadir dengan banyak efek samping yang terkait dengan pengkodean pertahanan, konkurensi, dan keamanan yang berada di luar cakupan jawaban ini.
Permusuhan nol
List.of
dan koleksi apa pun sejak Java 1.5 tidak mengizinkannya null
sebagai elemen. Mencoba meneruskan null
sebagai elemen atau bahkan pencarian akan menghasilkan file NullPointerException
.
Karena Arrays.asList
merupakan koleksi dari 1.2 (Collections Framework), memungkinkan null
s.
listOf.contains(null); // NullPointerException
unmodif.contains(null); // allowed
asList.contains(null); // allowed
Bentuk berseri
Karena List.of
telah diperkenalkan di Java 9 dan daftar yang dibuat dengan metode ini memiliki bentuk serialnya sendiri (biner), daftar tersebut tidak dapat dideserialisasi pada versi JDK sebelumnya (tanpa kompatibilitas biner ). Namun, Anda dapat membatalkan / membuat serial dengan JSON, misalnya.
Identitas
Arrays.asList
panggilan internal new ArrayList
, yang menjamin ketidaksetaraan referensi.
List.of
tergantung pada implementasi internal. Instans yang dikembalikan dapat memiliki persamaan referensi, tetapi karena ini tidak dijamin, Anda tidak dapat mengandalkannya.
asList1 == asList2; // false
listOf1 == listOf2; // true or false
Perlu disebutkan bahwa daftar adalah sama (melalui List.equals
) jika mereka berisi elemen yang sama dalam urutan yang sama, terlepas dari bagaimana mereka dibuat atau operasi apa yang mereka dukung.
asList.equals(listOf); // true i.f.f. same elements in same order
Implementasi (peringatan: detail dapat berubah seiring versi)
Jika jumlah elemen dalam daftar List.of
2 atau kurang, elemen disimpan di bidang kelas khusus (internal). Contohnya adalah daftar yang menyimpan 2 elemen (sumber parsial):
static final class List2<E> extends AbstractImmutableList<E> {
private final E e0;
private final E e1;
List2(E e0, E e1) {
this.e0 = Objects.requireNonNull(e0);
this.e1 = Objects.requireNonNull(e1);
}
}
Jika tidak, mereka disimpan dalam larik dengan cara yang mirip dengan Arrays.asList
.
Efisiensi Ruang dan Waktu
The List.of
implementasi yang berbasis lapangan (ukuran <2) melakukan sedikit lebih cepat pada beberapa operasi. Sebagai contoh, size()
dapat mengembalikan konstanta tanpa mengambil panjang array, dan contains(E e)
tidak memerlukan overhead iterasi.
Membuat daftar yang tidak dapat dimodifikasi melalui List.of
juga lebih cepat. Bandingkan konstruktor di atas dengan 2 tugas referensi (dan bahkan satu untuk jumlah elemen yang berubah-ubah) ke
Collections.unmodifiableList(Arrays.asList(...));
yang membuat 2 daftar ditambah biaya tambahan lainnya. Dalam hal ruang, Anda menghemat UnmodifiableList
pembungkus ditambah beberapa sen. Pada akhirnya, penghematan yang HashSet
setara lebih meyakinkan.
Waktu kesimpulan: gunakan List.of
ketika Anda menginginkan daftar yang tidak berubah dan Arrays.asList
ketika Anda menginginkan daftar yang dapat berubah (seperti yang ditunjukkan di atas).