Katılıyorum:
- O (1) 'in genel itfa edilmiş karmaşıklığı
- kötü bir
hashCode()
uygulama birden fazla çarpışmaya neden olabilir, bu da en kötü durumda her nesnenin aynı kovaya gittiği anlamına gelir, dolayısıyla her bir kova a ile destekleniyorsa O ( N ) List
.
- Java 8'den beri
HashMap
, her bir grupta kullanılan Düğümleri (bağlantılı liste) dinamik olarak Ağaç Düğümleri (bir liste 8 öğeden daha büyük olduğunda kırmızı-siyah ağaç) ile değiştirerek O'nun ( logN ) en kötü performansına yol açar .
Ancak,% 100 kesin olmak istiyorsak, bu gerçek değil. hashCode()
Anahtarın uygulanması ve türü Object
(değişmez / önbelleğe alınmış veya Koleksiyon olma) da gerçek karmaşıklığı katı terimlerle etkileyebilir.
Aşağıdaki üç durumu varsayalım:
HashMap<Integer, V>
HashMap<String, V>
HashMap<List<E>, V>
Aynı karmaşıklığa mı sahipler? Birincisinin amortize edilmiş karmaşıklığı, beklendiği gibi, O (1). Ancak, geri kalanı için, hashCode()
arama elemanını da hesaplamamız gerekir , bu da algoritmamızdaki dizileri ve listeleri taramamız gerekebileceği anlamına gelir.
Yukarıdaki tüm dizilerin / listelerin boyutunun k olduğunu varsayalım . Daha sonra, HashMap<String, V>
ve HashMap<List<E>, V>
O (k) amortize edilmiş karmaşıklığa ve benzer şekilde, Java8'de O ( k + logN ) en kötü duruma sahip olacaktır.
* Bir String
anahtar kullanmanın daha karmaşık bir durum olduğunu unutmayın, çünkü bu değişmezdir ve Java, sonucunu hashCode()
özel bir değişkende önbelleğe alır hash
, bu nedenle yalnızca bir kez hesaplanır.
/** Cache the hash code for the string */
private int hash; // Default to 0
Ancak, yukarıdaki durum da en kötü halini yaşıyor, çünkü Java'nın String.hashCode()
uygulaması, hash == 0
hesaplamadan önce olup olmadığını kontrol ediyor hashCode
. Ama hey, hashcode
"f5a5a608" gibi a çıktısı veren boş olmayan Dizeler var , buraya bakın , bu durumda not alma yardımcı olmayabilir.