Java Collections Framework uygulamaları için Big-O özeti? [kapalı]


164

Yakında bir "Java kilitlenme kursu" öğretiyor olabilirim. Kitle üyelerinin Big-O notasyonunu bileceğini varsaymak muhtemelen güvenli olsa da, çeşitli koleksiyon uygulamalarındaki çeşitli işlemlerin sırasının ne olduğunu bildiklerini varsaymak muhtemelen güvenli değildir.

Kendim bir özet matris oluşturmak için zaman alabilir, ancak zaten orada bir yerde kamu malı varsa, tekrar kullanmak istiyorum (tabii ki uygun kredi ile).

Kimsenin işaretçisi var mı?


Burada, bazı çok yaygın Java nesnelerini ve işlemlerinin Big-O gösterimini kullanarak maliyetinin ne kadar olduğunu tartışırken faydalı bulduğum bir bağlantı. objectissues.blogspot.com/2006/11/…
Nick

Kamusal alanda olmasa da, Maurice Naftalin ve Philip Wadler tarafından hazırlanan mükemmel Java Generics and Collections , farklı koleksiyon sınıflarındaki bölümlerde çalışma zamanı bilgileri özetlerini listeler.
Fabian Steeg

1
Bu performans ölçütünün herhangi bir faydası olur mu?
Tehdit

Yanıtlar:


149

Bu web sitesi oldukça iyi ancak Java'ya özgü değil: http://bigocheatsheet.com/ İşte bu bağlantının çalışmaması durumunda bir resim


27
İşte bu yüzden URL'leri cevap olarak kullanmıyoruz. Bu belge / sunucu, anlayabildiğim kadarıyla artık mevcut değil!
Jason Mock

1
@Ben J Linkler artık çalışmıyor
Vikas V

Web arşiv bağlantıları da artık bozuk.
MikeFHay

Yeni çalışma URL'leri eklendi. Çaba gösterdiğiniz için teşekkürler, çok yararlı.
Tejas C

1
@AndreaZilio LinkedList.remove (Object), komşuyu zaten bildiğinizi varsayarak sabit bir süredir. Komşuyu tanımıyorsanız, önce onu bulmanın doğrusal zamanı.
Paul Evans

217

Java Generics and Collections kitabında bu bilgiler bulunur (sayfalar: 188, 211, 222, 240).

Uygulamaları listele:

                      get  add  contains next remove(0) iterator.remove
ArrayList             O(1) O(1) O(n)     O(1) O(n)      O(n)
LinkedList            O(n) O(1) O(n)     O(1) O(1)      O(1)
CopyOnWrite-ArrayList O(1) O(n) O(n)     O(1) O(n)      O(n)

Uygulamaları ayarla:

                      add      contains next     notes
HashSet               O(1)     O(1)     O(h/n)   h is the table capacity
LinkedHashSet         O(1)     O(1)     O(1) 
CopyOnWriteArraySet   O(n)     O(n)     O(1) 
EnumSet               O(1)     O(1)     O(1) 
TreeSet               O(log n) O(log n) O(log n)
ConcurrentSkipListSet O(log n) O(log n) O(1)

Harita uygulamaları:

                      get      containsKey next     Notes
HashMap               O(1)     O(1)        O(h/n)   h is the table capacity
LinkedHashMap         O(1)     O(1)        O(1) 
IdentityHashMap       O(1)     O(1)        O(h/n)   h is the table capacity 
EnumMap               O(1)     O(1)        O(1) 
TreeMap               O(log n) O(log n)    O(log n) 
ConcurrentHashMap     O(1)     O(1)        O(h/n)   h is the table capacity 
ConcurrentSkipListMap O(log n) O(log n)    O(1)

Kuyruk uygulamaları:

                      offer    peek poll     size
PriorityQueue         O(log n) O(1) O(log n) O(1)
ConcurrentLinkedQueue O(1)     O(1) O(1)     O(n)
ArrayBlockingQueue    O(1)     O(1) O(1)     O(1)
LinkedBlockingQueue   O(1)     O(1) O(1)     O(1)
PriorityBlockingQueue O(log n) O(1) O(log n) O(1)
DelayQueue            O(log n) O(1) O(log n) O(1)
LinkedList            O(1)     O(1) O(1)     O(1)
ArrayDeque            O(1)     O(1) O(1)     O(1)
LinkedBlockingDeque   O(1)     O(1) O(1)     O(1)

Java.util paketi için javadoc'un alt kısmında bazı iyi bağlantılar bulunur:


3
Dizinin ortasındaki veya sonundaki öğeyi silerseniz, hangi vaka senaryosu için bu rakamlar olduğunu belirtmeniz gerekir; örneğin Arraylist'ten silme O (n) alabilir.
Temel Reis

@popeye O genellikle en kötü durum değil mi?
Yassin Hajaj

@ Popeye tarafından belirtildiği gibi, cevabın ne olduğu hakkında net bir açıklama olmalıdır. Vaka, zaman karmaşıklığı için ortalama / en kötü olabilir. Yanıtın tüm DS için "ortalama" bir durumu ifade ettiği anlaşılıyor.
Yashwin Munsadwala

12

Her koleksiyon sınıfı için Sun'dan Javadoc'lar genellikle tam olarak ne istediğinizi söyleyecektir. HashMap , örneğin:

Bu uygulama , hash fonksiyonunun elemanları kovalar arasında düzgün bir şekilde dağıttığını varsayarak, temel işlemler (get and put) için sabit zamanlı performans sağlar . Koleksiyon görünümleri üzerinde yineleme , HashMap örneğinin ( kapasite sayısı) artı boyutuyla (anahtar / değer eşleme sayısı) orantılı olarak zaman gerektirir .

TreeMap :

Bu uygulama, includeKey , get, put ve remove işlemleri için garantili günlük (n) zaman maliyeti sağlar.

TreeSet :

Bu uygulama , temel işlemler (ekleme, kaldırma ve içerir) için garantili günlük (n) zaman maliyeti sağlar .

(benimkini vurgula)


HashMap kısmına katılmıyorum. Sun'ın pozisyonunu biliyorum, ama ... get örneğin içerilen nesnelerin boyutunda doğrusal olabilen obj.equals (anahtar) olarak adlandırılmalıdır. Bu karşılaştırma için genellikle alanları okumalısınız. İstisnalar tamsayı veya dize (stajyer) olurdu ???
Taşma

Her şeyden önce, eğer yanlışlarsa, sabit zamanlı performansı çürüten bir test senaryosu oluşturmak sizin için çok zor olmamalı mı? İkinci olarak, HashMap için kaynak koduna bakarsanız, haritadaki her tuşa eşittir () öğesini çağırmaz - yalnızca hashcode'lar eşit olduğunda.
matt b

5
Yukarıdaki alıntıyı okursanız, "hash fonksiyonunun elemanları kovalar arasında düzgün bir şekilde dağıttığı varsayılarak" sabit zaman olduğunu söylüyor. CS teorisinden, hash fonksiyonu "iyi" (ortalama olarak gerçekleşir) olduğunda hash tabloları sabit zaman işlemlerine sahiptir, ancak en kötü durumda doğrusal zaman alabilir.
newacct

4
@Overflown - teknik olarak, obj.equals () yönteminin karmaşıklık perspektifinden ne kadar uzun sürdüğü önemli değildir, çünkü koleksiyondaki öğe sayısıyla ilişkili olarak "sabit" in bir parçasıdır.
mikera

6

Yukarıdaki adam HashMap / HashSet ile TreeMap / TreeSet karşılaştırması yaptı.

ArrayList ve LinkedList hakkında konuşacağım:

ArrayList:

  • O (1) get()
  • itfa edilmiş O (1) add()
  • takmadan veya kullanan ortasında bir eleman silerseniz ListIterator.add()ya Iterator.remove(), bu O (n) aşağıdaki tüm unsurları kaydırmaya olacak

Bağlantılı liste:

  • O (n) get()
  • O (1) add()
  • takmadan veya kullanan ortasında bir eleman silerseniz ListIterator.add()ya Iterator.remove(), o olacak O (1)

1
if you insert or delete an element in the middle using ListIterator.add() or Iterator.remove(), it will be O(1) neden? önce ortada element bulmalıyız, o zaman neden O (n) değil?
MyTitle

@ MyTitle: tekrar okuyun. "kullanıyor ListIterator.add()veya Iterator.remove()" Bir yineleyicimiz var.
newacct
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.