JavaRush /Java Blog /Random-ID /10 Pertanyaan Teratas tentang Koleksi di Java
FedoraLinux
Level 21
Москва

10 Pertanyaan Teratas tentang Koleksi di Java

Dipublikasikan di grup Random-ID
Artikel tersebut merupakan terjemahan dari artikel " 10 pertanyaan teratas tentang Koleksi Java " . Di bawah ini adalah pertanyaan paling populer tentang koleksi di Java, yang ditanyakan dan didiskusikan di Stackowerflow. Sebelum Anda melihat pertanyaan-pertanyaan ini, ada baiknya melihat diagram hierarki kelas. 1. Kapan menggunakan LinkedList dan bukan ArrayList? ArrayList sebenarnya adalah sebuah array; elemen-elemennya dapat diakses langsung dengan indeks. Jika array meluap, diperlukan array baru dengan lebih banyak ruang. Menempatkan dan memindahkan semua elemen akan memakan waktu O(n). Selain itu, penambahan dan penghapusan elemen diperlukan untuk memindahkan elemen yang ada dalam array. Ini mungkin ketidaknyamanan terbesar dalam menggunakan ArrayList. LinkedList adalah daftar ganda tautan elemen. Jadi, untuk mengakses elemen di tengah, Anda harus mencari dari awal hingga akhir lembar. Di sisi lain, menambah dan menghapus elemen dalam LinkedList lebih cepat karena operasi ini hanya mengubah daftar itu sendiri. Saat-saat terburuk dibandingkan di bawah ini:
metode Daftar susunan Daftar Tertaut
dapatkan (indeks) HAI(1) Pada)
tambahkan (E) Pada) HAI(1)
tambahkan(E, indeks) Pada) Pada)
hapus (indeks) Pada) Pada)
Iterator.hapus() Pada) HAI(1)
Iterator.tambahkan(E) Pada) HAI(1)
Meskipun waktu berjalan, penggunaan memori harus dipertimbangkan secara individual untuk daftar besar. Dalam LinkedList, setiap node harus memiliki setidaknya dua pointer tambahan untuk menghubungkan node sebelumnya dan berikutnya, sedangkan dalam ArrayList, hanya diperlukan array elemen. Lebih banyak perbandingan daftar ArrayList, LinkedList dan Vector . 2. Setara yang efisien untuk menghapus elemen selama iterasi koleksi Satu-satunya cara yang benar untuk memodifikasi (menghapus elemen) koleksi selama iterasi adalah dengan menggunakan Iterator.remove() . Misalnya: Kesalahan paling umum adalah: Anda akan mendapatkan ConcurrentModificationException saat menjalankan kode di atas. Hal ini terjadi karena iterator dibuat untuk berpindah ke seluruh daftar, namun pada saat yang sama sheet diubah dengan memanggil Iterator.remove(). Seperti yang tertulis dalam dokumentasi untuk pengecualian ini, Iterator itr = list.iterator(); while(itr.hasNext()) { // do something itr.remove(); } for(Integer i: list) { list.remove(i); }
"umumnya tidak diperbolehkan bagi satu thread untuk memodifikasi koleksi sementara thread lain mengulanginya."
Secara umum, tidak dapat diterima jika satu thread memodifikasi koleksi sementara thread lain melintasinya. 3. Bagaimana cara mengubah array Daftar menjadi int[]? Cara termudah untuk melakukannya adalah dengan menggunakan ArrayUtils , yang terletak di perpustakaan Apache Commons Lang . int[] array = ArrayUtils.toPrimitive(list.toArray(new Integer[0])); Tidak ada jalan pintas untuk ekspresi ini di JDK. Ingatlah bahwa Anda tidak dapat menggunakan List.toArray() karena ekspresi ini mengonversi List menjadi Integer[] (yang bukan merupakan tipe primitif). Cara yang benar adalah dengan opsi berikut: int[] array = new int[list.size()]; for(int i=0; i < list.size(); i++) { array[i] = list.get(i); } 4. Bagaimana cara mengubah array int[] menjadi Daftar? Cara termudah juga adalah dengan menggunakan ArrayUtils di perpustakaan Apache Commons Lang , seperti di atas. List list = Arrays.asList(ArrayUtils.toObject(array)); Selain itu, tidak ada jalan pintas untuk ekspresi ini di JDK. 5. Apa cara terbaik untuk memfilter koleksi? Anda dapat menggunakan paket pihak ketiga seperti Guava atau Apache Commons Lang untuk meningkatkan fungsionalitas. Kedua paket ini memiliki metode filter() (di kelas Collections2 dari Guava dan CollectionUtils dari Apache). Metode filter() akan mengembalikan elemen yang cocok dengan Predikat yang diberikan. Di JDK semuanya lebih rumit. Kabar baiknya adalah predikat akan ditambahkan di Java 8 , tetapi untuk saat ini Anda perlu menggunakan Iterator untuk melakukan iterasi ke seluruh koleksi. Tentu saja, Anda dapat meniru jalur yang diikuti oleh Guava dan Apache dengan mengenal antarmuka Predicate yang baru. Sekarang kita dapat menggunakan kode berikut untuk memfilter koleksi: 6. Bagaimana cara mudah mengubah Daftar ke Kumpulan? Ada dua cara untuk melakukan hal ini, bergantung pada bagaimana Anda ingin mendefinisikan kesetaraan. Potongan kode pertama memasukkan daftar ke dalam HashSet. Duplikat dalam hal ini ditentukan terutama oleh kode hash(). Biasanya ini akan berhasil. Namun jika Anda perlu memperhitungkan jalur perbandingan, akan lebih baik jika menggunakan bagian kedua dari kode, di mana Anda dapat menentukan pembanding Anda sendiri. 7. Bagaimana cara menghapus elemen duplikat dari ArrayList? Pertanyaan ini agak berkaitan dengan pertanyaan di atas. Jika urutan elemen dalam ArrayList tidak menjadi masalah bagi Anda, langkah cerdas adalah menempatkan sheet dalam Set untuk menghapus duplikat, dan kemudian mengembalikannya ke Daftar. Di bawah ini adalah contohnya. Jika urutan elemen penting bagi Anda, maka urutannya dapat dipastikan dengan menempatkan daftar di LinkedHashSet , yang ada di JDK standar. 8. Koleksi yang diurutkan int[] array = {1,2,3,4,5}; List list = new ArrayList (); for(int i: array) { list.add(i); } Iterator itr = list.iterator(); while(itr.hasNext()) { int i = itr.next(); if (i > 5) { // filter all ints bigger than 5 itr.remove(); } } public interface Predicate { boolean test(T o); } public static void filter(Collection collection, Predicate predicate) { if ((collection != null) && (predicate != null)) { Iterator itr = collection.iterator(); while(itr.hasNext()) { T obj = itr.next(); if (!predicate.test(obj)) { itr.remove(); } } } } filter(list, new Predicate () { public boolean test(Integer i) { return i <= 5; } }); Set set = new HashSet (list); Set set = new TreeSet (aComparator); set.addAll(list); ArrayList** list = ... // initial a list with duplicate elements Set set = new HashSet (list); list.clear(); list.addAll(set); Ada beberapa cara untuk mendukung koleksi yang diurutkan di Java. Semuanya menyediakan koleksi dalam tatanan alami atau dengan pembanding tertentu. Dalam kasus tatanan alami, Anda juga perlu mengimplementasikan antarmuka Comparable pada elemen tersebut.
  1. Collections.sort() dapat mengurutkan Daftar. Sebagaimana dinyatakan dalam dokumentasi Java, pengurutan ini stabil dan menjamin kinerja n log(n).
  2. PriorityQueue menyediakan antrian yang teratur. Perbedaan antara PriorityQueue dan Collections.sort() adalah PriorityQueue mempertahankan urutan antrian sepanjang waktu, namun Anda hanya bisa mendapatkan elemen pertama dari antrian. Anda tidak dapat mengakses elemen seperti PriorityQueue.get(4) secara acak.
  3. Jika tidak ada duplikat dalam koleksi, Anda dapat memilih TreeSet . Juga seperti PriorityQueue, TreeSet mempertahankan kumpulan yang terurut setiap saat. Anda bisa mendapatkan elemen terkecil atau terbesar dari TreeSet, tetapi Anda tetap tidak dapat memiliki akses acak ke elemen tersebut.
Sederhananya, Collections.sort() menyediakan daftar pesanan satu kali. PriorityQueue dan TreeSet mempertahankan koleksi yang terurut setiap saat, dengan mengorbankan kurangnya akses yang diindeks ke elemen. 9. Collections.emptyList() atau instance baru Pertanyaan yang sama berlaku untuk blankMap() dan blankSet(). Kedua metode mengembalikan daftar kosong, tetapi Collections.emptyList() adalah daftar yang tidak dapat diubah. Ini berarti Anda tidak dapat menambahkan elemen baru ke daftar "kosong". Di latar belakang, setiap panggilan ke metode Collections.emptyList() sebenarnya tidak membuat instance baru dari daftar kosong. Sebaliknya, ia akan menggunakan kembali instance kosong yang sudah ada. Jika Anda sudah familiar dengan Singleton sebagai pola desain , Anda pasti mengerti apa yang dimaksud. Ini akan memberi Anda kinerja yang lebih baik jika sering dipanggil. 10 Menyalin koleksi, Collections.copy() Ada dua cara untuk menyalin daftar sumber ke daftar tujuan. Salah satu caranya adalah dengan menggunakan konstruktor ArrayList. Cara lainnya adalah dengan menggunakan metode Collections.copy() . Perhatikan pada baris pertama: kami mengalokasikan daftar yang panjangnya setidaknya sama dengan panjang daftar asli, karena dokumentasi Java tentang koleksi mengatakan: ArrayList dstList = new ArrayList (srcList);
Daftar tujuan setidaknya harus sepanjang daftar sumber.
Artinya, daftar akhir tidak boleh lebih pendek dari daftar aslinya. Kedua metode ini merupakan penyalinan yang dangkal. Lalu apa perbedaan kedua metode ini? Pertama, Collections.copy() tidak akan mengalokasikan ulang kapasitas koleksi dstList, meskipun dstList tidak memiliki cukup ruang untuk memuat semua elemen dari srcList. Sebaliknya, ia akan memunculkan IndexOutOfBoundsException . Mungkin ada yang bertanya apakah ada manfaatnya. Alasannya adalah hal ini memastikan bahwa metode berjalan secara linear dalam waktu. Ini juga cocok bila Anda ingin menggunakan kembali array daripada mengalokasikan ulang memori di konstruktor ArrayList. Daripada menyimpulkan Jika setelah membaca artikel Anda masih memiliki pertanyaan, silakan tanyakan di kolom komentar. Juga, jika Anda menemukan ketidakakuratan dalam terjemahan atau kesalahan lainnya, tulislah ke PM, itu akan diperbaiki, dan Anda akan berterima kasih. Asli. ArrayList dstList = new ArrayList (srcList.size()); Collections.copy(dstList, srcList);
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION