JDK7與JDK8中HashMap的區別


關於JDK7中的HashMap源碼分析可移步: http://blog.csdn.net/qq_17305249/article/details/76877193
        總的來說,JDK7中的hashMap底層采用了數組+鏈表的數據結構實現數據存儲,隨着存儲數據量的增大,Hash碰撞會越來越頻繁。也就意味着鏈表會越來越長,查找效率不斷降低。
        JDK8的出現解決了這個問題,對與hashMap采用了新的數據結構:數組+鏈表/紅黑樹(當鏈表長度達到某個閾值時,鏈表就轉換成了紅黑樹)
        當鏈表的結點大於閾值(初始為8)時,將鏈表轉換成紅黑樹
        例如JDK8中HashMap的put方法:
1
public V put(K key, V value) {
2
        return putVal(hash(key), key, value, false, true);
3
 }
4
 
5
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
6
                   boolean evict) {
7
        Node<K,V>[] tab;
8
    Node<K,V> p; 
9
    int n, i;
10
    //如果當前map中無數據,執行resize方法。並且返回n
11
        if ((tab = table) == null || (n = tab.length) == 0)
12
            n = (tab = resize()).length;
13
     //如果要插入的鍵值對要存放的這個位置剛好沒有元素,那么把他封裝成Node對象,放在這個位置上就完事了
14
        if ((p = tab[i = (n - 1) & hash]) == null)
15
            tab[i] = newNode(hash, key, value, null);
16
    //否則的話,說明這上面有元素
17
        else {
18
            Node<K,V> e; K k;
19
        //如果這個元素的key與要插入的一樣,那么就替換一下,也完事。
20
            if (p.hash == hash &&
21
                ((k = p.key) == key || (key != null && key.equals(k))))
22
                e = p;
23
        //1.如果當前節點是TreeNode類型的數據,執行putTreeVal方法
24
            else if (p instanceof TreeNode)
25
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
26
            else {
27
        //還是遍歷這條鏈子上的數據,跟jdk7沒什么區別
28
                for (int binCount = 0; ; ++binCount) {
29
                    if ((e = p.next) == null) {
30
                        p.next = newNode(hash, key, value, null);
31
            //2.完成了操作后多做了一件事情,判斷,並且可能執行treeifyBin方法
32
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
33
                            treeifyBin(tab, hash);//構建紅黑樹
34
                        break;
35
                    }
36
                    if (e.hash == hash &&
37
                        ((k = e.key) == key || (key != null && key.equals(k))))
38
                        break;
39
                    p = e;
40
                }
41
            }
42
            if (e != null) { // existing mapping for key
43
                V oldValue = e.value;
44
                if (!onlyIfAbsent || oldValue == null) //true || --
45
                    e.value = value;
46
           //3.
47
                afterNodeAccess(e);
48
                return oldValue;
49
            }
50
        }
51
        ++modCount;
52
    //判斷閾值,決定是否擴容
53
        if (++size > threshold)
54
            resize();
55
        //4.
56
        afterNodeInsertion(evict);
57
        return null;
58
    }

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: