简体   繁体   中英

Why does java.util.HashMap use a linked list internally

My conceptual understanding of a java.util.HashMap is as follows:

  1. Its main asset over other Map implementations is constant lookup time, assuming there are no collisions. For this reason the underlying implementation uses an array of fixed length - the only data structure in computer science that has O(1) lookup.

  2. The fixed length array used to store the Map entries is initialised to a given size upon instantiation and expanded (by expanded, I mean a larger array is created and the values copied across) as the size of the Map approaches the length of the fixed length array.

  3. When a value is put into the Map, the key value pair are put into an internal linked list implementation for the given key. When there is a collision subsequent key value pairs are appended to the list.

  4. When getting from the Map, the hashCode() of the key is used to derive the array index of the internal linked list implementation and you either have your value if the list has size 1, or you iterate through the list calling equals() on the key of each element until you find your values.

Based on point 2, HashMap has to expand an array, an operation which is surely linear. Why does it use an internal linked list implementation (O(n) lookup) for collision resolution? Why doesn't it use a datastructure with O(log n) lookup, like a binary or red black tree, to enhance performance?

http://openjdk.java.net/jeps/180

As of Java 8, HashMap does fall back to a binary tree if there are enough collisions.

Although it doesn't guarantee O(1) insertion time, it does have amortized O(1) insertion time, which is to say that if you insert a large number of elements one by one, the total time taken to insert them will be proportional to the number of elements you insert.

It won't improve this to alter the data structure used for the buckets. The point of the array expansion is to ensure that the expected number of entries in each bucket is constant ; this means that there's still constant-time insertion and lookup, even with a linked list.

The numbers are very carefully worked out, in terms of when to expand, and how much to expand by (doubling the size of the array). It is a very similar technique to that used in ArrayList , to guarantee amortized O(1) addition to the list.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM