简体   繁体   中英

how are buckets created in hashmap?

I am a bit confused about internal working of hash map. I have created a Hashmap with default capacity 16 and my key class always return a hash code value 1. So when i will enter the 13th element to this map it will double the map size.
1. How many buckets will be there in hash map ?
2. Does hash map create a new bucket on demand (ie When hash code does not match to any existing bucket's hash code value)?

Although it's a bit late but this might help fellow users looking for an answer to this question.

As of your first question, How many buckets will be there in hash map ? -- There will be 16 buckets as that's the default capacity if you don't specify it in the constructor argument while instantiating HashMap.

Now let's come to the second question ie Does hash map create a new bucket on demand (ie When hash code does not match to any existing bucket's hash code value)?

It will be interesting to look at the implementation of Hashmap's put method here .

public V put(K key, V value) {

    if (key == null)
        return putForNullKey(value);

    int hash = hash(key.hashCode());
    int i = indexFor(hash, table.length);

    for (Entry<K, V> e = table[i]; e != null; e = e.next) {
        Object k;

        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }
    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

If you look closely, the method hash which accepts key's hashmap as argument is called inside the put method. The job of this method is to defend against poor quality hash functions . After this indexFor method is used, to identify the index (bucket) where the element will be inserted. The index returned by this method always points to an existing bucket. So, there isn't a case where the key's hashcode points to a bucket that doesn't exist.

So when does a hashmap creates a new bucket? It's neatly explained in javase docs .

It says: "An instance of HashMap has two parameters that affect its performance: initial capacity and load factor. The capacity is the number of buckets in the hash table, and the initial capacity is simply the capacity at the time the hash table is created. The load factor is a measure of how full the hash table is allowed to get before its capacity is automatically increased. When the number of entries in the hash table exceeds the product of the load factor and the current capacity, the hash table is rehashed (that is, internal data structures are rebuilt) so that the hash table has approximately twice the number of buckets. "

Hope that helps.

When you create a HashMap with the default capacity (16), you create it with 16 buckets (ie, the capacity == the number of buckets).

  1. When the capacity is doubled, the number of buckets is doubled.

  2. The hashCode always matches some existing bucket, since modulus N (where N is the current capacity) is applied on the computed hash in order to find the bucket it belongs to.

I'm more from C#, but Java is quite similar to it :) So forgive me if anythings wrong here. Feel free to correct it.

The number of available buckets can't be told easily. It depends on the number of elements in the map (load factor). The load factor is kept about 75% of the total capacity. This is related to the fact, that if there are two identical hashes one of them has to be rehashed (to get another position in the map) -> 75% is a good tradeoff between performance and size. Whenever there are more than 75% the size is doubled (ie 75% of 16 is 12; with the 13th element the size is doubled). And anyhow this is also an answer to the second question.

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