Apa perbedaan antara
1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); //copy
2.List<Integer> list2 = Arrays.asList(ia);
dimana ia
array bilangan bulat.
Saya mengetahui bahwa beberapa operasi tidak diizinkan masuk list2
. kenapa gitu? bagaimana cara menyimpannya dalam memori (referensi / salinan)?
Ketika saya mengocok daftar, list1
tidak memengaruhi larik asli tetapi memengaruhi list2
. Tapi tetap saja list2
agak membingungkan.
Bagaimana ArrayList
disorot ke daftar berbeda dengan membuat yang baruArrayList
list1 differs from (1)
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
java
list
collections
Dineshkumar
sumber
sumber
Lists.newArrayList(ia)
membuat salinan independen, seperti opsi pertama. Ini lebih umum dan lebih baik untuk dilihat.Jawaban:
Pertama, mari kita lihat apa fungsinya:
Ini mengambil array
ia
dan membuat pembungkus yang mengimplementasikanList<Integer>
, yang membuat array asli tersedia sebagai daftar. Tidak ada yang disalin dan semuanya, hanya satu objek pembungkus yang dibuat. Operasi pada pembungkus daftar disebarkan ke larik asli. Ini berarti bahwa jika Anda mengocok list wrapper, array asli juga akan diacak, jika Anda menimpa elemen, elemen tersebut akan ditimpa dalam array asli, dll. Tentu saja, beberapaList
operasi tidak diizinkan pada wrapper, seperti menambahkan atau menghapus elemen dari daftar, Anda hanya dapat membaca atau menimpa elemen.Perhatikan bahwa pembungkus daftar tidak diperpanjang
ArrayList
- ini adalah jenis objek yang berbeda.ArrayList
s memiliki array internal sendiri, di mana mereka menyimpan elemen-elemennya, dan dapat mengubah ukuran array internal, dll. Wrapper tidak memiliki array internalnya sendiri, ia hanya menyebarkan operasi ke array yang diberikan padanya.Di sisi lain, jika Anda selanjutnya membuat array baru sebagai
kemudian Anda membuat yang baru
ArrayList
, yang merupakan salinan lengkap dan independen dari yang asli. Meskipun di sini Anda juga membuat pembungkus menggunakanArrays.asList
, itu hanya digunakan selama pembangunan yang baruArrayList
dan sampah dikumpulkan sesudahnya. Struktur baruArrayList
ini sepenuhnya tidak bergantung pada larik aslinya. Ini berisi elemen yang sama (baik array asli danArrayList
referensi baru ini adalah bilangan bulat yang sama dalam memori), tetapi membuat array internal baru, yang menyimpan referensi. Jadi ketika Anda mengocoknya, menambah, menghapus elemen, dll., Larik asli tidak berubah.sumber
List<Integer>
jenis variabel Anda (atau argumen metode, dll.). Ini membuat kode Anda lebih umum dan Anda dapat dengan mudah beralih keList
implementasi lain sesuai kebutuhan, tanpa harus menulis ulang banyak kode.Nah ini karena yang
ArrayList
dihasilkanArrays.asList()
bukan dari jenisnyajava.util.ArrayList
.Arrays.asList()
menciptakanArrayList
tipejava.util.Arrays$ArrayList
yang tidak meluasjava.util.ArrayList
tetapi hanya meluasjava.util.AbstractList
sumber
Dalam hal ini,
list1
adalah tipeArrayList
.Di sini, daftar dikembalikan sebagai
List
tampilan, artinya hanya memiliki metode yang dilampirkan ke antarmuka itu. Oleh karena itu mengapa beberapa metode tidak diperbolehkanlist2
.Di sini, Anda sedang membuat file
ArrayList
. Anda hanya memberikan nilai di konstruktor. Ini bukan contoh casting. Dalam casting, mungkin terlihat seperti ini:sumber
Saya lumayan telat disini, lagian merasa penjelasan dengan referensi doc akan lebih baik bagi yang mencari jawaban.
ArrayList memiliki banyak konstruktor yang kelebihan beban
public ArrayList () - // mengembalikan arraylist dengan kapasitas default 10
public ArrayList (Koleksi c)
public ArrayList (int initialCapacity)
Jadi, ketika kita mengirimkan objek yang dikembalikan Arrays.asList yaitu List (AbstractList) ke konstruktor kedua di atas, itu akan membuat array dinamis baru (ukuran array ini bertambah saat kita menambahkan lebih banyak elemen daripada kapasitasnya dan juga elemen baru tidak akan memengaruhi array orignal ) menyalin dangkal array asli ( salinan dangkal berarti menyalin di atas referensi saja dan tidak membuat set baru dari objek yang sama seperti di orignal array)
sumber
atau
Pernyataan Di Atas menambahkan pembungkus pada larik input. Jadi metode seperti tambah & hapus tidak akan berlaku pada objek referensi daftar 'namesList'.
Jika Anda mencoba menambahkan elemen dalam larik / daftar yang ada, maka Anda akan mendapatkan "Exception in thread" main "java.lang.UnsupportedOperationException".
Operasi di atas hanya bisa dibaca atau dilihat.
Kita tidak dapat melakukan operasi tambah atau hapus pada objek daftar. Tapi
atau
Dalam pernyataan di atas Anda telah membuat instance konkret dari kelas ArrayList dan mengirimkan daftar sebagai parameter.
Dalam kasus ini, metode add & remove akan berfungsi dengan baik karena kedua metode berasal dari kelas ArrayList jadi di sini kita tidak akan mendapatkan UnSupportedOperationException.
Perubahan yang dibuat dalam objek Arraylist (metode menambah atau menghapus elemen di / dari daftar array) tidak akan tercermin dalam objek java.util.List asli.
sumber
Pertama-tama kelas Array adalah kelas utilitas yang berisi no. metode utilitas untuk beroperasi pada Array (berkat kelas Array jika tidak kita perlu membuat metode kita sendiri untuk bertindak pada objek Array)
asList () metode:
asList
metode adalah salah satu metode utilitasArray
kelas, itu adalah metode statis itulah sebabnya kita dapat memanggil metode ini dengan nama kelasnya (sepertiArrays.asList(T...a)
)ArrayList
objek baru , itu hanya mengembalikan referensi Daftar keArray
objek yang ada (jadi sekarang setelah menggunakanasList
metode, dua referensi keArray
objek yang ada dibuat)List
objek, TIDAK boleh bekerja pada objek Array ini menggunakanList
referensi seperti misalnya,Array
ukuran s tetap panjangnya, maka Anda jelas tidak dapat menambah atau menghapus elemen dariArray
objek menggunakanList
referensi ini (sepertilist.add(10)
ataulist.remove(10);
kalau tidak itu akan memunculkan UnsupportedOperationException)Array
(karena Anda beroperasi pada objek Array yang ada dengan menggunakan referensi daftar)Dalam kasus pertama Anda membuat
Arraylist
objek baru (dalam kasus ke-2 hanya referensi ke objek Array yang ada dibuat tetapi bukanArrayList
objek baru ), jadi sekarang ada dua objek yang berbeda, satu adalahArray
objek dan yang lainnya adalahArrayList
objek dan tidak ada koneksi di antara mereka (jadi perubahan dalam satu objek tidak akan dipantulkan / terpengaruh di objek lain (yaitu dalam kasus 2Array
danArraylist
merupakan dua objek yang berbeda)kasus 1:
kasus 2:
sumber
Banyak orang telah menjawab detail mekanisnya, tetapi perlu diperhatikan: Ini adalah pilihan desain yang buruk, oleh Java.
asList
Metode Java didokumentasikan sebagai "Mengembalikan daftar ukuran tetap ...". Jika Anda mengambil hasilnya dan memanggil (katakan).add
metode tersebut, ia akan melemparUnsupportedOperationException
. Ini adalah perilaku yang tidak intuitif! Jika sebuah metode mengatakan ia mengembalikan aList
, harapan standarnya adalah ia mengembalikan objek yang mendukung metode antarmukaList
. Seorang pengembang tidak perlu mengingat mana dari sekianutil.List
metode yang dibuatList
yang tidak benar-benar mendukung semuaList
metode.Jika mereka telah menamai metodenya
asImmutableList
, itu masuk akal. Atau jika mereka hanya memiliki metode mengembalikan yang sebenarnyaList
(dan menyalin array pendukung), itu akan masuk akal. Mereka memutuskan untuk memilih kinerja runtime dan nama pendek, dengan mengorbankan Prinsip Kejutan Terkecil dan praktik baik-OO dalam menghindariUnsupportedOperationException
s.(Juga, perancang mungkin telah membuat
interface ImmutableList
, untuk menghindari sejumlah besarUnsupportedOperationException
s.)sumber
Perhatikan bahwa, di Java 8, 'ia' di atas harus berupa Integer [] dan bukan int []. Arrays.asList () dari larik int mengembalikan daftar dengan satu elemen. Saat menggunakan potongan kode OP, kompilator akan menangkap masalah, tetapi beberapa metode (misalnya Collections.shuffle ()) akan diam-diam gagal melakukan apa yang Anda harapkan.
sumber
sumber
Arrays.asList()
metode ini mengembalikan implementasinya sendiri dari List. Ini mengambil array sebagai argumen dan membangun metode dan atribut di atasnya, karena tidak menyalin data apa pun dari array tetapi menggunakan array asli, ini menyebabkan perubahan dalam array asli saat Anda memodifikasi daftar dikembalikan oleh
Arrays.asList()
metode.di samping itu.
ArrayList(Arrays.asList());
adalah konstruktorArrayList
kelas yang mengambil list sebagai argumen dan mengembalikanArrayList
yang tidak bergantung pada list yaitu.Arrays.asList()
dalam hal ini disahkan sebagai argumen. itulah mengapa Anda melihat hasil ini;sumber
Di baris 2,
Arrays.asList(ia)
mengembalikanList
referensi objek kelas dalam yang ditentukan di dalamArrays
, yang juga disebutArrayList
tetapi bersifat pribadi dan hanya diperluasAbstractList
. Ini berarti apa yang dikembalikan dariArrays.asList(ia)
adalah objek kelas yang berbeda dari yang Anda dapatkannew ArrayList<Integer>
.Anda tidak dapat menggunakan beberapa operasi ke baris 2 karena kelas privat dalam
Arrays
tidak menyediakan metode tersebut.Lihatlah tautan ini dan lihat apa yang dapat Anda lakukan dengan kelas dalam privat: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ Arrays.java # Arrays.ArrayList
Baris 1 membuat
ArrayList
objek baru menyalin elemen dari apa yang Anda dapatkan dari baris 2. Jadi Anda dapat melakukan apa pun yang Anda inginkan karenajava.util.ArrayList
menyediakan semua metode tersebut.sumber
Ringkasan perbedaan -
ketika daftar dibuat tanpa menggunakan metode operator baru Arrays.asList () itu mengembalikan Wrapper yang artinya
1. Anda dapat melakukan operasi tambah / perbarui.
2. perubahan yang dilakukan dalam larik asli juga akan direfleksikan ke Daftar dan sebaliknya.
sumber
Menanggapi beberapa komentar yang mengajukan pertanyaan tentang perilaku Arrays.asList () sejak Java 8:
sumber