Saya setuju dengan:
- kompleksitas umum yang diamortisasi dari O (1)
hashCode()implementasi yang buruk dapat mengakibatkan beberapa tabrakan, yang berarti bahwa dalam kasus terburuk setiap objek pergi ke ember yang sama, sehingga O ( N ) jika setiap ember didukung oleh a List.
- sejak Java 8,
HashMapsecara dinamis menggantikan Nodes (daftar tertaut) yang digunakan di setiap bucket dengan TreeNodes (pohon merah-hitam ketika daftar menjadi lebih besar dari 8 elemen) yang menghasilkan kinerja terburuk O ( logN ).
Tapi, ini BUKAN kebenaran sepenuhnya jika kita ingin 100% tepat. Implementasi hashCode()dan jenis kunci Object(tidak berubah / di-cache atau menjadi Koleksi) juga dapat memengaruhi kompleksitas nyata dalam istilah yang ketat.
Mari kita asumsikan tiga kasus berikut:
HashMap<Integer, V>
HashMap<String, V>
HashMap<List<E>, V>
Apakah mereka memiliki kompleksitas yang sama? Nah, kompleksitas amortisasi yang pertama adalah, seperti yang diharapkan, O (1). Tetapi, untuk sisanya, kita juga perlu menghitung hashCode()elemen pencarian, yang berarti kita mungkin harus melintasi array dan daftar dalam algoritma kita.
Mari kita asumsikan bahwa ukuran semua array / daftar di atas adalah k . Kemudian, HashMap<String, V>dan HashMap<List<E>, V>akan ada O (k) kompleksitas diamortisasi dan juga, O ( k + logN ) kasus terburuk di Java8.
* Perhatikan bahwa menggunakan Stringkunci adalah kasus yang lebih kompleks, karena tidak dapat diubah dan Java menyimpan hasil cache hashCode()dalam variabel pribadi hash, jadi itu hanya dihitung sekali.
/** Cache the hash code for the string */
private int hash; // Default to 0
Tapi, di atas juga memiliki kasus terburuknya sendiri, karena String.hashCode()implementasi Java sedang memeriksa hash == 0sebelum komputasi hashCode. Tapi hei, ada String non-kosong yang menghasilkan a hashcodenol, seperti "f5a5a608", lihat di sini , dalam hal ini memoisasi mungkin tidak membantu.