Apakah ada alternatif abadi untuk array primitif di Jawa? Membuat array primitif final
sebenarnya tidak mencegah seseorang melakukan sesuatu seperti
final int[] array = new int[] {0, 1, 2, 3};
array[0] = 42;
Saya ingin elemen array tidak dapat diubah.
int[]
dannew int[]
JAUH lebih mudah untuk mengetik daripadaList<Integer>
dannew ArrayList<Integer>
? XDJawaban:
Tidak dengan array primitif. Anda harus menggunakan Daftar atau struktur data lain:
sumber
Arrays.asList
adalah tidak unmodifiable. docs.oracle.com/javase/7/docs/api/java/util/... "Mengembalikan daftar ukuran tetap yang didukung oleh array yang ditentukan. (Perubahan ke daftar yang dikembalikan" write through "ke array.)"Arrays.asList()
memang tampaknya tidak dapat dimodifikasi dalam arti bahwa Anda tidak dapatadd
atauremove
item yang dikembalikanjava.util.Arrays.ArrayList
( tidak menjadi bingung denganjava.util.ArrayList
) - operasi ini tidak diimplementasikan. Mungkin @mauhiz mencoba mengatakan ini? Tapi tentu saja Anda dapat memodifikasi elemen yang sudah adaList<> aslist = Arrays.asList(...); aslist.set(index, element)
, jadijava.util.Arrays.ArrayList
tentu saja bukan tidak mungkin , QED Menambahkan komentar hanya untuk menekankan perbedaan antara hasilasList
dan normalArrayList
Rekomendasi saya adalah untuk tidak menggunakan array atau
unmodifiableList
tetapi untuk menggunakan Guava 's ImmutableList , yang ada untuk tujuan ini.sumber
Collections.unmodifiableList
cukup untuk membuat Daftar tidak berubah?Seperti yang telah dicatat orang lain, Anda tidak dapat memiliki array yang tidak dapat diubah di Jawa.
Jika Anda benar-benar membutuhkan metode yang mengembalikan array yang tidak mempengaruhi array asli, maka Anda harus mengkloning array setiap kali:
Jelas ini agak mahal (karena Anda akan membuat salinan lengkap setiap kali Anda memanggil getter), tetapi jika Anda tidak dapat mengubah antarmuka (untuk menggunakan
List
misalnya) dan tidak dapat mengambil risiko klien mengubah internal Anda, maka mungkin perlu.Teknik ini disebut membuat salinan defensif.
sumber
clone()
atau diArrays.copy()
sini?Ada satu cara untuk membuat array yang tidak dapat diubah di Jawa:
Array dengan 0 elemen (jelas) tidak dapat dimutasi.
Ini sebenarnya bisa berguna jika Anda menggunakan
List.toArray
metode untuk mengonversiList
sebuah array. Karena bahkan array kosong membutuhkan beberapa memori, Anda dapat menyimpan alokasi memori itu dengan membuat array kosong konstan, dan selalu meneruskannya ketoArray
metode. Metode itu akan mengalokasikan array baru jika array yang Anda lewati tidak memiliki cukup ruang, tetapi jika itu (daftar itu kosong), itu akan mengembalikan array yang Anda lewati, memungkinkan Anda untuk menggunakan kembali array itu setiap kali Anda memanggiltoArray
sebuah mengosongkanList
.sumber
Satu lagi jawaban
sumber
Pada Java 9 Anda dapat menggunakan
List.of(...)
, JavaDoc .Metode ini mengembalikan kekal
List
dan sangat efisien.sumber
Jika Anda perlu (karena alasan kinerja atau untuk menghemat memori) asli 'int' bukan 'java.lang.Integer', maka Anda mungkin perlu menulis kelas pembungkus Anda sendiri. Ada berbagai implementasi IntArray di internet, tetapi tidak ada (saya menemukan) tidak berubah: Koders IntArray , Lucene IntArray . Mungkin ada yang lain.
sumber
Sejak Guava 22, dari paket
com.google.common.primitives
Anda dapat menggunakan tiga kelas baru, yang memiliki jejak memori lebih rendah dibandingkan denganImmutableList
.Mereka juga memiliki pembangun. Contoh:
atau, jika ukurannya diketahui pada waktu kompilasi:
Ini adalah cara lain untuk mendapatkan tampilan array yang tidak berubah dari Java primitif.
sumber
Tidak, ini tidak mungkin. Namun, orang dapat melakukan sesuatu seperti ini:
Ini membutuhkan menggunakan pembungkus, dan merupakan Daftar, bukan array, tetapi yang terdekat Anda akan dapatkan.
sumber
valueOf()
itu, autoboxing akan membereskannya. JugaArrays.asList(0, 2, 3, 4)
akan jauh lebih ringkas.valueOf()
adalah memanfaatkan cache objek Integer internal untuk mengurangi konsumsi / daur ulang memori.int
keInteger
meskipun; hanya harus berhati-hati sebaliknya.Dalam beberapa situasi, akan lebih ringan untuk menggunakan metode statis ini dari perpustakaan Google Guava:
List<Integer> Ints.asList(int... backingArray)
Contoh:
List<Integer> x1 = Ints.asList(0, 1, 2, 3)
List<Integer> x1 = Ints.asList(new int[] { 0, 1, 2, 3})
sumber
Jika Anda ingin menghindari sifat berubah-ubah dan tinju, tidak ada jalan keluar dari kotak. Tapi Anda bisa membuat kelas yang menyimpan larik primitif di dalamnya dan menyediakan akses hanya baca ke elemen melalui metode.
sumber
Metode (elemen ... elemen) di Java9 dapat digunakan untuk membuat daftar tetap menggunakan hanya satu baris:
Metode di atas mengembalikan daftar yang tidak berubah yang mengandung sejumlah elemen yang berubah-ubah. Dan menambahkan bilangan bulat ke daftar ini akan menghasilkan
java.lang.UnsupportedOperationException
pengecualian. Metode ini juga menerima satu array sebagai argumen.sumber
Meskipun benar itu
Collections.unmodifiableList()
berfungsi, kadang-kadang Anda mungkin memiliki perpustakaan besar yang memiliki metode yang sudah didefinisikan untuk mengembalikan array (misalnyaString[]
). Untuk mencegahnya, Anda dapat mendefinisikan array bantu yang akan menyimpan nilai:Untuk menguji:
Tidak sempurna, tetapi setidaknya Anda memiliki "pseudo immutable array" (dari perspektif kelas) dan ini tidak akan merusak kode terkait.
sumber
Nah .. array berguna untuk dilewatkan sebagai konstanta (jika mereka) sebagai parameter varian.
sumber
int[]
, pemanggil mungkin berasumsi mereka dapat melakukan apa yang mereka inginkan dengan array itu tanpa mempengaruhi internal API.