Hangi Java Koleksiyonunu kullanmalıyım?


127

Bu soruda C ++ 11'de bir Standart Kitaplık kabını verimli bir şekilde nasıl seçebilirim? C ++ koleksiyonlarını seçerken kullanabileceğiniz kullanışlı bir akış şemasıdır.

Bunun hangi koleksiyonu kullanmaları gerektiğinden emin olmayan insanlar için yararlı bir kaynak olduğunu düşündüm, bu yüzden Java için benzer bir akış şeması bulmaya çalıştım ve bulamadım.

İnsanların Java'da programlama yaparken kullanacakları doğru Koleksiyonu seçmelerine yardımcı olacak hangi kaynaklar ve "kopya sayfaları" mevcut? Kişiler hangi Liste, Set ve Harita uygulamalarını kullanmaları gerektiğini nasıl biliyor?


Java Generics and Collections (Naftalin & Wadler) kitabında bununla ilgili bir bölüm var.
Christophe Roussy

Yanıtlar:


293

Benzer bir akış şeması bulamadığım için kendim yapmaya karar verdim.

Bu akış şeması senkronize erişim, iş parçacığı güvenliği vb. Veya eski koleksiyonlar gibi şeyleri denemez ve kapsamaz, ancak 3 standart Seti , 3 standart Harita ve 2 standart Listeyi kapsar .

görüntü açıklamasını buraya girin

Bu görüntü, bu yanıt için oluşturulmuştur ve Creative Commons Attribution 4.0 Uluslararası Lisansı altında lisanslanmıştır . En basit atıf, bu soruya veya bu cevaba bağlanmaktır.

Diğer kaynaklar

Muhtemelen en yararlı diğer referans, her Koleksiyonu açıklayan oracle belgelerinin sonraki sayfasıdır .

HashSet ve TreeSet

Ne zaman HashSetveya TreeSetburada kullanılacağına dair ayrıntılı bir tartışma var: Hashset vs Treeset

ArrayList ve LinkedList

Ayrıntılı tartışma: LinkedList, ArrayList yerine ne zaman kullanılır?


Güzel! Ama kararlarınıza LinkedListkarşı ArrayListçıkmalıyım. İlk olarak, liste önemli boyuttaysa LinkedListtercih edilir. LinkedListöğe başına ek yükü vardır, bu nedenle bellek tüketimi açısından bir ArrayList. Ayrıca, erişimin çoğu listenin sonunda ise, ArrayListsabit zamanlı rastgele eleman erişimi sağladığı için bir tercih edilir. A'nın ninci elemanına erişim LinkedListbir O(n)işlemdir. ... Aslında, bağlantılı bir liste kullanma kararı hemen hemen her zaman "hayır" olmalıdır .
Matt Ball

2
@MattBall Çoğunlukla sana katılıyorum. Ancak Java LinkedListçift ​​bağlantılı bir listedir, bu nedenle hem başlangıçta hem de sonda erişim hızlıdır. Bunu kullanmanızı tavsiye etmeden önce, her üç sorunun da üzerindeki şubelerin evet yanıtı vermesi gerektiğini not edeceksiniz.LinkedList - bu nedenle, çoğu durumda yanıtın hayır olduğu konusunda size katılıyorum. Listenin sonlarından sürekli olarak bir şeyler ekleyip çıkardığınız kuyruklar ve kuyruklar gibi şeyler, iyi bir kullanım durumu alanıdır LinkedList.
Tim B

@MattBall Bellek kullanımı çok daha karmaşık bir durumdur, çünkü LinkedListöğe başına daha fazla bellek kullanır ... belleği ArrayListasla serbest bırakmaz . Bu, bazen büyük bir boyuta ulaşan ancak genellikle küçük olan bir listeniz varsa ArrayList, daha kötü bellek performansı vereceği anlamına gelir . Kendisinin bellek yükü, Listiçerdiği öğelere kıyasla genellikle (her zaman olmasa da) küçüktür.
Tim B

Map<K,V>değiljava.util.collection
Mehraj Malik

@MehrajMalik Hmm, etiketleme belirsiz, katılıyorum. Java.util içindeki Koleksiyonu kastetmiştim. yani java.util. * koleksiyon adını buraya girin *
Tim B

66

Eşzamanlı olmayan, senkronize olmayan ana koleksiyonların özeti

Collection: "Öğeler" adı verilen, sırasız bir öğe "çantasını" temsil eden bir arayüz. "Sonraki" öğe tanımsızdır (rastgele).

  • Set: CollectionYinelemesiz a'yı temsil eden bir arabirim .
    • HashSet: A Set, a tarafından desteklenmektedir Hashtable. Sipariş önemsiz olduğunda en hızlı ve en küçük bellek kullanımı.
    • LinkedHashSetA HashSetiçinde ortak elemanlara bağlı bir listesi ek ekleme düzenine . "Sonraki" öğe, sonraki en son eklenen öğedir.
    • TreeSet: SetElemanların a Comparator(tipik olarak doğal sıralama ) ile sıralandığı A. En yavaş ve en büyük bellek kullanımı, ancak karşılaştırıcıya dayalı sıralama için gereklidir.
    • EnumSet: SetTek bir enum türü için özelleştirilmiş son derece hızlı ve verimli .
  • List: CollectionÖğeleri sıralı olan ve her birinin konumunu temsil eden bir sayısal dizini temsil eden bir arabirim , burada sıfır ilk öğe ve (length - 1)sondur.
    • ArrayList: ListDizinin, en az öğe sayısı (listenin "boyutu") kadar büyük bir uzunluğa ("kapasite" denir) sahip olduğu bir dizi tarafından desteklenen bir dizi. Boyut kapasiteyi aştığında ( (capacity + 1)-thöğe eklendiğinde), dizi yeni bir kapasite ile yeniden oluşturulur - bu yeniden oluşturma (new length * 1.5), kullandığı için hızlıdır System.arrayCopy(). Öğelerin silinmesi ve eklenmesi / eklenmesi, tüm komşu öğelerin (sağdaki) o alana veya bu alanın dışına kaydırılmasını gerektirir. Herhangi bir öğeye erişim hızlıdır, çünkü yalnızca (element-zero-address + desired-index * element-size)konumunu bulmak için hesaplama gerektirir .Çoğu durumda , ArrayLista yerine a tercih edilir LinkedList.
    • LinkedList: ListHer biri "önceki" ve "sonraki" komşularına bağlı bir dizi nesnenin desteklediği bir. A LinkedListaynı zamanda bir Queueve'dir Deque. Elemanlara erişim, ilk veya son elemandan başlayarak ve istenen dizine ulaşılana kadar geçiş yapılır. İstenilen dizine çapraz geçiş yoluyla ulaşıldığında ekleme ve silme, yeni öğeye işaret etmek veya şimdi silinen öğeyi atlamak için yalnızca hemen komşu bağlantıların yeniden eşleştirilmesinin önemsiz bir meselesidir.
  • Map: CollectionHer öğenin tanımlayıcı bir "anahtara" sahip olduğu bir arabirimi temsil eden bir arabirim - her öğe bir anahtar / değer çiftidir.
    • HashMap: MapAnahtarların sırasız olduğu ve bir Hashtable.
    • LinkedhashMap: Anahtarlar, ekleme sırasına göre sıralanır .
    • TreeMap: MapAnahtarların bir Comparator(tipik olarak doğal sıralama) ile sıralandığı bir yer .
  • Queue: CollectionÖğelerin tipik olarak bir uca eklendiği ve diğerinden kaldırıldığı bir yeri temsil eden bir arabirim (FIFO: ilk giren, ilk çıkar).
  • Stack: CollectionÖğelerin tipik olarak aynı uçtan eklendiği (itildiği) ve kaldırıldığı (atıldığı) bir yeri temsil eden bir arabirim (LIFO: son giren, ilk çıkar).
  • Deque: "Çift uçlu sıra" nın kısaltması, genellikle "deste" olarak okunur. Tipik olarak yalnızca her iki uca eklenen ve okunan (ortasına değil) bağlantılı bir liste.

Temel koleksiyon diyagramları:

diyagram

Bir öğenin eklenmesini bir ArrayListve ile karşılaştırmak LinkedList:

diyagram


2
Her yerde bulabileceğiniz en iyi kısa yazlık :)
roottraveller

11

Daha basit bir resim burada. Kasıtlı olarak basitleştirilmiş!

  1. Koleksiyon , "öğeler" adı verilen (aynı türden) verileri tutan herhangi bir şeydir. Daha spesifik bir şey varsayılmaz.

  2. Liste bir olduğunu endeksli her öğenin bir dizine sahip olduğu veri koleksiyonudur. Dizi gibi bir şey ama daha esnek.

    Listedeki veriler, ekleme sırasını korur.

    Tipik işlem: n'inci öğeyi alın.

  3. Takım a, elemanların torbası , her bir eleman, sadece bir kez (elementler ile ayırt edilirequals() yöntem.

    Kümedeki veriler çoğunlukla sadece orada hangi verilerin olduğunu bilmek için depolanır .

    Tipik işlem: listede bir eleman olup olmadığını söyleyin.

  4. Harita , Liste gibi bir şeydir, ancak öğelere tamsayı indeksleriyle erişmek yerine, onlaraherhangi bir nesne olan anahtarıyla erişirsiniz. PHP'deki dizi gibi :)

    Haritadaki veriler anahtarlarına göre aranabilir.

    Tipik işlem: kimliğine göre bir öğe alın (burada ID yalnızca intList durumunda olduğu gibi değil, herhangi bir türdendir ).

Farklılıklar

  • Ayarla ve Eşle: Ayarla'da verileri kendi başlarına , Harita'da ise anahtarlarıyla aramanızı sağlar .

  • Liste ve Harita: List'de öğeye intindekslerine göre (Listedeki konum) erişirken , Harita'da herhangi bir türden hangi os anahtarına göre (tipik olarak: ID)

  • Liste ve Küme: Listedeki öğeler konumlarına göre bağlanır ve kopyalanabilirken, Kümede öğeler yalnızca "mevcuttur" (pr mevcut değildir) ve benzersizdir (anlamında equals()veya compareTo()için SortedSet)


1

Çok basit: Değerleri kendileriyle eşlenmiş anahtarlarla saklamanız gerekiyorsa, Harita arayüzüne gidin, aksi takdirde yinelenebilecek değerler için List'i kullanın ve koleksiyonunuzda yinelenen değerler istemiyorsanız son olarak Set arayüzünü kullanın.

İşte tam açıklama http://javatutorial.net/choose-the-right-java-collection , akış şeması vb. Dahil


1

Harita

Bir seçerseniz Map, Java 11 ile birlikte gelen on uygulamanın her birinin özelliklerini özetleyen bu tabloyu yaptım.

Özelliklerini karşılaştıran Java 11'deki harita uygulamaları tablosu



-2

Hangi Java Koleksiyonunu kullanmalıyım?

Hangi sorunu çözmeye çalıştığınıza veya hangi gereksinimlere sahip olduğunuza bağlıdır.

Örnekler:

  1. Öğelerin depolanırken sıralanmasını istiyor musunuz? HashSet
  2. (Anahtar, Değer) çiftlerinin saklanmasını istiyor musunuz? HashMap
  3. Eklendiğinde elemanların sırasının korunmasını istiyor musunuz? ArrayList, LinkedList
  4. (Anahtar, Değer) Çiftindeki Anahtarların sıralanmasını istiyor musunuz? - güçlü metin
  5. Sorununuzu çözmek için bir Yığın uygulamak ister misiniz? - Yığın
  6. FIFO (İlk Giren İlk Çıkar) erişimine sahip olmak istiyor musunuz? - Kuyruk
  7. Yalnızca BENZERSİZ öğelerin saklanmasını mı istiyorsunuz? - HashSet
  8. (Anahtar, Değer) depolarken anahtara "Boş" olarak izin vermek istiyor musunuz? - HashMap
  9. (Anahtar, Değer) çifti için NULL değer istemiyor musunuz? HashTable

Madde 4'teki güçlü metin , örneğin ConcurrentSkipListMap (K, V) ile değiştirilse bile , bu cevap Tim B'nin karar grafiğine , aliteralmind'ın "kısa liste açıklamalarına" ne katıyor ?
greybeard

İlk noktanız, HashSet verileri sıralamaz, hatta ekleme sırası korunmaz. Bunu TreeSet ile değiştirmelisiniz
Saurabh Mishra
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.