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 }
未完成,待以后详细解析
标签:Java,HashMap,value,return,源码,key,firstNode,hash,null 来源: https://www.cnblogs.com/cbhe/p/12616915.html