Java HashMap 源码解析

 1 final int hash(Object key){
 2    
 3     // 如果为null则返回0
 4     if(key == null){
 5         return 0;
 6     }
 7 
 8     // 不为null则先获取hashCode
 9     int h = key.hashCode();
10 
11     // hashCode 前16位维持原样,后16位为原来前16位与后16位的异或(以增加分散程度)
12     int hash = h ^ h>>>16;
13 
14     return hash;
15 }
 1 public V get(Object key){
 2     // 先计算key的hash值
 3     int hash = hash(key);
 4 
 5     // 调用getNode方法
 6     Node<K, V> e = getNode(hash, key);
 7 
 8     // 找不到则返回null
 9     if(e == null){
10         return null;
11     }
12 
13     // 找到了就返回value
14     return e.value;
15 }
 1 final Node<K, V> getNode(int hash, Object key){
 2 
 3     // 如果table为空则返回null
 4     if(table == null || table.length <= 0){
 5         return null;
 6     }
 7 
 8     // table不为空时,使用hash在table中查找key
 9     int tableLen = table.length;
10     
11     // hash 和 tableLen-1 进行按位与操作,目的是使keyIndex不超过tableLen-1
12     int keyIndex = (tableLen-1) & hash;
13     
14     Node<K,V> firstNode = table[keyIndex];
15 
16     // firstNode 的hash与入参hash相等且firstNode的key与入参key相等,则该结点就是需要返回的结点
17     if(firstNode.hash == hash && 
18       (firstNode.key == key)||(firstNode.key != null &&firstNode.key.equals(key))){
19         
20         return firstNode;
21     }
22 
23     // 如果firstNode不是要找的node,则根据不同的数据结构再继续往下找
24     if(firstNode.next == null){
25         return null;
26     }
27 
28     // 根据不同的数据结构决定如何进一步寻找
29     if(firstNode instanceof TreeNode){
30         // 树形结构(红黑树)
31         TreeNode root = (TreeNode<K,V>)firstNode;
32 
33         // 调用 getTreeNode 方法(下一篇文章会详细讲解)
34         return root.getTreeNode(hash, key);
35     } else {
36         // 链表结构
37         for(Node<K, V> e = firstNode.next; e != null; e = e.next){
38             
39             if(e.hash == hash &&
40                 ((e.key == key)||(e.key != null && e.key.equals(key))){
41                 return e;
42             }
43         }
44     }
45 
46     return null;
47 }
 1 public V put(K key, V value){
 2     
 3     // 先找到key对应的node,如果没有则新建
 4     if(table == null || table.length <= 0){
 5         // resize方法用来创建和初始化table
 6         resize();
 7     }
 8 
 9     int hash = hash(key);
10     Node<K, V> firstNode = table[(table.length-1)&hash];
11 
12     // 如果在table中没有找到,则新建一个node
13     if(firstNode == null){
14         table[(table.length-1)&hash]
15             = new Node<>(hash, key, value, null);
16         return null;
17     }
18 
19     // 如果table中可以找到
20     // 先判断firstNode是否为要找的node
21     if(firstNode.hash == hash 
22         &&((firstNode.key == key)||(firstNode.key != null && firstNode.key.equals(key)))){
23 
24         // 设置为新值,并将旧值返回
25         V oldValue = firstNode.value;
26         firstNode.value = value;
27         return oldValue;
28     }
29 
30     // 判断firstNode下是否有链表或树结构
31     if(firstNode.next == null){
32         firstNode.next 
33             = = new Node<>(hash, key, value, null);
34         return null;
35     }
36 
37     // 根据不同的数据结构继续查找
38     if(firstNode instanceof TreeNode){
39         // 树形结构,直接调用putTreeVal方法
40         Node<K, V> e = putTreeVal(hash, key, value);
41         if(e == null){
42             return null;
43         }
44 
45         // return 旧值
46         return e.value;
47     } else {
48         int listSize;// 记录链表长度
49         Node<K, V> e;
50         for(e = firstNode.next, linkSize = 2; e != null; e = e.next, linkSize++){
51             Node<K, V> eNext = e.next;
52             if(eNext == null){
53                 // 未找到
54                 e.next = new Node<K,V>(hash, key, value, null);
55                 
56                 // 链表超过指定长度时,将其调整为树状结构
57                 if(linkSize + 1 >= TREEIFY_THRESHOLD){
58                     treeify(table);
59                 }
60                 return null;
61             }
62             if(eNext.hash == hash && 
63             ((eNext.key == key)||(eNext.key != null && eNext.key.equals(key)))){
64                 // 找到了
65                 V oldValue= eNext.value;
66                 eNext.value = value;
67                 return oldValue;
68             }
69         }
70     }
71 
72     // 正常情况下不会执行到这里的
73     return null;
74 }

未完成,待以后详细解析

上一篇:vue项目国际化,基于vue-i18n实现


下一篇:Linux终端中文输出