Koleksi Java mana yang harus saya gunakan?

127

Dalam pertanyaan ini Bagaimana saya bisa secara efisien memilih wadah Perpustakaan Standar dalam C ++ 11? adalah bagan alur yang berguna untuk digunakan saat memilih koleksi C ++.

Saya pikir ini adalah sumber yang berguna untuk orang-orang yang tidak yakin koleksi mana yang harus mereka gunakan jadi saya mencoba untuk menemukan bagan alur yang sama untuk Jawa dan tidak dapat melakukannya.

Sumber daya apa dan "lembar contekan" yang tersedia untuk membantu orang memilih Koleksi yang tepat untuk digunakan saat pemrograman di Jawa? Bagaimana orang tahu implementasi Daftar, Set, dan Peta apa yang harus mereka gunakan?

Tim B
sumber
Buku Java Generics and Collections (Naftalin & Wadler) memiliki bab tentang ini.
Christophe Roussy

Jawaban:

293

Karena saya tidak dapat menemukan diagram alur yang sama, saya memutuskan untuk membuatnya sendiri.

Diagram alir ini tidak mencoba dan penutup hal-hal seperti akses disinkronkan, benang pengaman dll atau koleksi warisan, tetapi tidak menutupi 3 standar Set s, 3 standar Peta dan 2 standar Daftar s.

masukkan deskripsi gambar di sini

Gambar ini dibuat untuk jawaban ini dan dilisensikan di bawah Lisensi Internasional Creative Commons Attribution 4.0. Atribusi paling sederhana adalah dengan menautkan ke pertanyaan ini atau jawaban ini.

Sumber daya lainnya

Mungkin referensi lain yang paling berguna adalah halaman berikut dari dokumentasi oracle yang menjelaskan setiap Koleksi .

HashSet vs TreeSet

Ada diskusi terperinci tentang kapan harus menggunakan HashSetatau di TreeSetsini: Hashset vs Treeset

ArrayList vs LinkedList

Diskusi terperinci: Kapan menggunakan LinkedList daripada ArrayList?

Tim B
sumber
Bagus! Tapi saya harus tidak setuju dengan keputusan LinkedListvs Anda ArrayList. Pertama, jika daftar memiliki ukuran yang signifikan, LinkedListlebih disukai. LinkedListmemiliki overhead per-elemen, sehingga asymptotically lebih buruk dalam hal konsumsi memori daripada ArrayList. Juga, jika sebagian besar akses berada di akhir daftar, ArrayListlebih disukai karena memberikan akses elemen acak waktu konstan. Mengakses nelemen th dari LinkedListadalah O(n)operasi. ... Faktanya, keputusan untuk menggunakan daftar tertaut harus selalu "tidak".
Matt Ball
2
@MattBall Saya setuju dengan Anda untuk sebagian besar. Namun Java LinkedListadalah daftar yang ditautkan ganda, jadi akses di awal dan di akhir keduanya cepat. Anda akan mencatat bahwa dari cabang-cabang di atas ketiga pertanyaan harus dijawab ya sebelum saya merekomendasikan menggunakan LinkedList- jadi dengan kata lain saya setuju dengan Anda bahwa dalam kebanyakan kasus jawabannya adalah tidak. Hal-hal seperti antrian dan dequeues di mana Anda terus menambahkan dan menghapus hal-hal dari ujung area daftar kasus penggunaan yang baik LinkedList.
Tim B
@MattBall Penggunaan memori adalah situasi yang jauh lebih rumit karena sementara LinkedListmenggunakan lebih banyak memori per elemen ... ArrayListtidak pernah melepaskan memori. Itu berarti bahwa jika Anda memiliki daftar yang terkadang tumbuh dengan ukuran besar tetapi biasanya kecil maka ArrayListakan memberikan kinerja memori yang lebih buruk. Memori overhead Listitu sendiri biasanya (walaupun tidak selalu) kecil dibandingkan dengan elemen yang dikandungnya juga.
Tim B
Map<K,V>bukan bagian darijava.util.collection
Mehraj Malik
@ MehrajMalik Hmm, pelabelan itu ambigu saya setuju. Maksudku Koleksi di dalam java.util. yaitu java.util. * masukkan nama koleksi di sini *
Tim B
66

Ringkasan koleksi utama yang tidak bersamaan, tidak disinkronkan

Collection: Antarmuka yang mewakili "tas" tanpa urutan item, disebut "elemen". Elemen "selanjutnya" tidak terdefinisi (acak).

  • Set: Antarmuka yang mewakili Collectiontanpa duplikat.
    • HashSet: A Setdidukung oleh a Hashtable. Penggunaan memori tercepat dan terkecil, ketika memesan tidak penting.
    • LinkedHashSet: A HashSetdengan tambahan daftar yang ditautkan untuk mengaitkan elemen dalam urutan penyisipan . Elemen "berikutnya" adalah elemen berikutnya yang paling baru disisipkan.
    • TreeSet: A di Setmana elemen dipesan oleh Comparator(biasanya pemesanan alami ). Penggunaan memori paling lambat dan terbesar, tetapi perlu untuk pemesanan berbasis komparator.
    • EnumSet: SetKustomisasi yang sangat cepat dan efisien untuk tipe enum tunggal.
  • List: Sebuah antarmuka yang mewakili Collectionelemen yang dipesan dan masing-masing memiliki indeks numerik yang mewakili posisinya, di mana nol adalah elemen pertama, dan (length - 1)merupakan yang terakhir.
    • ArrayList: A Listdidukung oleh array, di mana array memiliki panjang (disebut "kapasitas") yang setidaknya sama besar dengan jumlah elemen ("ukuran" daftar). Ketika ukuran melebihi kapasitas (ketika (capacity + 1)-thelemen ditambahkan), array diciptakan kembali dengan kapasitas baru (new length * 1.5)- rekreasi ini cepat, karena digunakan System.arrayCopy(). Menghapus dan menyisipkan / menambahkan elemen mengharuskan semua elemen tetangga (ke kanan) digeser ke dalam atau keluar dari ruang itu. Mengakses elemen apa pun dengan cepat, karena hanya memerlukan perhitungan (element-zero-address + desired-index * element-size)untuk menemukan lokasi itu. Dalam sebagian besar situasi , ArrayLista lebih disukai daripada a LinkedList.
    • LinkedList: ListDidukung oleh serangkaian objek, masing-masing ditautkan ke tetangga "sebelumnya" dan "berikutnya". A LinkedListjuga a Queuedan Deque. Mengakses elemen dilakukan mulai dari elemen pertama atau terakhir, dan melintasi hingga indeks yang diinginkan tercapai. Penyisipan dan penghapusan, setelah indeks yang diinginkan tercapai melalui traversal adalah masalah sepele memetakan ulang hanya link tetangga langsung untuk menunjuk ke elemen baru atau memotong elemen yang sekarang dihapus.
  • Map: Antarmuka yang mewakili di Collectionmana setiap elemen memiliki "kunci" pengidentifikasi - setiap elemen adalah pasangan nilai kunci.
    • HashMap: A di Mapmana kunci tidak teratur, dan didukung oleh a Hashtable.
    • LinkedhashMap: Kunci dipesan berdasarkan urutan penyisipan .
    • TreeMap: A di Mapmana kunci dipesan oleh Comparator(biasanya pemesanan alami).
  • Queue: Sebuah antarmuka yang mewakili Collectionelemen tempat, biasanya, ditambahkan ke satu ujung, dan dihapus dari yang lain (FIFO: masuk pertama, keluar pertama).
  • Stack: Sebuah antarmuka yang mewakili Collectionelemen tempat, biasanya, ditambahkan (didorong) dan dihapus (muncul) dari ujung yang sama (LIFO: last-in, first-out).
  • Deque: Pendek untuk "antrian ujung ganda", biasanya diucapkan "dek". Daftar tertaut yang biasanya hanya ditambahkan dan dibaca dari kedua ujung (bukan tengah).

Diagram koleksi dasar:

diagram

Membandingkan penyisipan elemen dengan ArrayListdan LinkedList:

diagram

Aliteralmind
sumber
2
Terbaik dalam musim panas yang singkat yang dapat
dicapai di
11

Gambar yang lebih sederhana ada di sini. Disederhanakan dengan sengaja!

  1. Koleksi adalah segala sesuatu yang menyimpan data yang disebut "elemen" (dari tipe yang sama). Tidak ada yang lebih spesifik yang dianggap.

  2. Daftar adalahkumpulan data yang diindeks di mana setiap elemen memiliki indeks. Sesuatu seperti array, tetapi lebih fleksibel.

    Data dalam daftar menjaga urutan penyisipan.

    Operasi khas: dapatkan elemen ke-n.

  3. Set adalah sekumpulan elemen , masing-masing elemen hanya sekali (elemen dibedakan menggunakanequals()metodemereka.

    Data dalam set sebagian besar disimpan hanya untuk mengetahui data apa yang ada.

    Operasi khas: memberi tahu jika ada elemen dalam daftar.

  4. Peta adalah sesuatu seperti Daftar, tetapi alih-alih mengakses elemen dengan indeks integernya, Anda mengaksesnya dengan kunci mereka, yang merupakan objek apa pun. Suka array dalam PHP :)

    Data dalam Peta dapat dicari dengan kunci mereka.

    Operasi khas: dapatkan elemen dengan ID-nya (di mana ID dari jenis apa pun, tidak hanya intseperti dalam Daftar).

Perbedaannya

  • Atur dan Peta: di Mengatur Anda mencari data sendiri , sementara di Peta dengan kunci mereka .

  • Daftar dan Peta: di elemen Daftar Anda mengakses dengan intindeks mereka (posisi dalam Daftar), sementara di Peta dengan kunci mereka yang os dari jenis apa pun (biasanya: ID)

  • Daftar dan Set: dalam Daftar elemen terikat oleh posisi mereka dan dapat digandakan, sedangkan di Set elemen hanya "hadir" (pr tidak ada) dan unik (dalam arti equals(), atau compareTo()untuk SortedSet)

Honza Zidek
sumber
1

Ini sederhana: jika Anda perlu menyimpan nilai dengan kunci yang dipetakan untuk mereka pergi untuk antarmuka Peta, jika tidak gunakan Daftar untuk nilai yang dapat diduplikasi dan akhirnya menggunakan antarmuka Set jika Anda tidak ingin nilai digandakan dalam koleksi Anda.

Berikut ini penjelasan lengkapnya: http://javatutorial.net/choose-the-right-java-collection , termasuk flowchart dll

filip_j
sumber
1

Peta

Jika memilih Map, saya membuat tabel ini merangkum fitur masing-masing dari sepuluh implementasi yang dibundel dengan Java 11.

Tabel implementasi peta di Java 11, membandingkan fitur-fiturnya

Basil Bourque
sumber
0

Koleksi umum, Koleksi umum masukkan deskripsi gambar di sini

Aliaksandr Shpak
sumber
-2

Koleksi Java mana yang harus saya gunakan?

Itu tergantung pada masalah apa yang Anda coba selesaikan atau persyaratan apa yang Anda miliki.

Contoh:

  1. Apakah Anda ingin elemen diurutkan saat menyimpannya? HashSet
  2. Apakah Anda ingin pasangan (Kunci, Nilai) disimpan? HashMap
  3. Apakah Anda ingin urutan elemen saat dimasukkan dipertahankan? ArrayList, LinkedList
  4. Apakah Anda ingin Pasangan Kunci (Kunci, Nilai) diurutkan? - teks yang kuat
  5. Apakah Anda ingin menerapkan Stack untuk menyelesaikan masalah Anda? - Stack
  6. Apakah Anda ingin memiliki akses FIFO (First in First out)? - Antrian
  7. Apakah Anda ingin hanya elemen UNIK yang disimpan? - HashSet
  8. Apakah Anda ingin mengizinkan kunci sebagai "Null" saat menyimpan (Kunci, Nilai)? - HashMap
  9. Apakah Anda ingin Tidak ada nilai NULL untuk pasangan (Kunci, Nilai)? HashTable
Aviral Kumar
sumber
Bahkan dengan teks yang kuat pada item 4 digantikan oleh, katakanlah, ConcurrentSkipListMap (K, V) , apa yang ditambahkan jawaban ini ke grafik keputusan Tim B , ke "deskripsi daftar pendek" aliteralmind ?
greybeard
Poin pertama Anda, HashSet tidak mengurutkan data, bahkan urutan penyisipan tidak dipertahankan. Anda harus mengubahnya dengan TreeSet
Saurabh Mishra