The difference between HashMap and HashTable, in-depth understanding

Both HashMap and HashTable are collection objects stored in Key-Value pairs. Each has its own advantages and each has its own shortcomings. Today I will talk about the direct differences between the two.

The differences are as follows:

  • HashMap thread-safe execution efficiency is high, HashTable thread-safe execution efficiency is low
  • HashMap can store empty keys, HashTable cannot store empty keys

Next, I will explore these two points.
1. HashMap thread-unsafe execution efficiency is high, HashTable thread-safe execution efficiency is low.
This is because the underlying methods of HashMap are not locked, and they are not modified by synchronized , so its execution efficiency is relatively fast, while the underlying HashTable The method is modified with synchronized , so its execution efficiency is relatively slow.
The code of several key methods of HashMap is as follows:
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
HashTable code is as follows:
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
when multiple threads share the same variable at the same time for writing operations, thread safety issues may occur Therefore in the case of high concurrency, HashMap not we should use, but HashTable is not the best choice, the best choice would be ConcurrentHashMap segmented lock it mainly uses the principles and CAS no locks (optimistic locking)
want If you have a deeper understanding, you can check this blog by programmer Xiaohui

HashMap can store empty keys, HashTable cannot store empty keys. You
can check the code of JDK1.7, because JDK1.7 is easier to understand. First
look at the method of HashMap

// HashMap的put方法
 public V put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null)
             // key为null调用putForNullKey(value)
             return putForNullKey(value);
        int hash = hash(key);
        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;
    }
 /**
     * Offloaded version of put for null keys
     */
    private V putForNullKey(V value) {
        for (Entry<K,V> e = table[0]; e != null; e = e.next) {
            if (e.key == null) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }
        modCount++;
        addEntry(0, null, value, 0);
        return null;
    }

When the put method of HashMap, the second judgment is that the key is null and then enter the putForNullKey(V value) method.
You can see that the previous for loop is to find the element whose key is null in the table[0] linked list. If If found, the value is reassigned to the value of this element, and the original value is returned.
If the above for loop is not found, add this element to the head of the talbe[0] linked list.

HashTable did not do this processing. It directly uses the Key to calculate the hashCode value. At this time, if the key is not obtained, it will report a null pointer error.
Insert picture description here
We can see that the error has been reported in the local
Insert picture description here
HashMap if the key is empty. Yes, at the same time there is no hashCode, so where is the value stored? The default storage table[0] From the code of hashMap1.7, we can see
whether the HashMap can store the key as an object?
This answer is also possible
because the generic String, Object, etc. we usually use are all objects.
Insert picture description here
We use the new object of the current class as the key of the HashMap and get the value correctly.

What is the difference between extended hashcode and equal() The
hashCode() method and the equal() method are actually the same. In Java, they are used to compare whether two objects are equal or not, so equal() can already achieve the function of comparison. , Why hashCode()?
Because the rewritten equal() is generally more comprehensive and complex, so the efficiency is relatively low, and using hashCode() for comparison, you only need to generate a hash value for comparison, and the efficiency is high, then hashCode() Why is equal() even if the efficiency is so high?
Because hashCode() is not completely reliable, sometimes different objects will generate the same hashcode (the possible problem of generating hash value formula, similar to the hash collision array of hashMap to linked list), so hashCode() can only be said to be Most of the time reliable, not absolutely reliable, so we can get:

  • 1. The hashCode() of two objects with equal() must be equal, that is, the comparison with equal() is absolutely reliable.

  • 2. Two objects with equal hashCode() have equal() not necessarily equal, that is, hashCode() is not absolutely reliable.

    If you need a lot of and fast comparison, if you use equal() to do it is obviously too inefficient, so the solution is, whenever you need to compare, first use hashCode() to compare, if the hashCode() is different, then Indicates that these two objects are definitely not equal (that is, there is no need to use equal() to compare). If the hashCode() is the same,
    then compare their equal(). If equal() is also the same, it means that the two The objects are really the same, which can greatly improve the efficiency and ensure the absolute correctness of the comparison!

Guess you like

Origin blog.csdn.net/G_whang/article/details/112687708