欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

HashMap的源码及底层实现原理介绍

程序员文章站 2022-10-03 13:48:04
哈希表的初始化1.HashMap map = new HashMap<>();当创建HashMap集合对象的时候,在jdk8前,是在HashMap的构造方法中创建一个长度是16的 Entry[] table 用来存储键值对数据的。在jdk8以后不是在HashMap的构造方法底层创建数组了,是在第一次调用put方法时创建的数组 Node[] table 用来存储键值对数据,来看jdk1.8后的源码其中HashMap的部分变量成员先列出来//一个...

哈希表的初始化

1.HashMap<String, Integer> map = new HashMap<>();
当创建HashMap集合对象的时候,在jdk8前,是在HashMap的构造方法中创建一个长度是16的 Entry[] table 用来存储键值对数据的。在jdk8以后不是在HashMap的构造方法底层创建数组了,是在第一次调用put方法时创建的数组 Node[] table 用来存储键值对数据,来看jdk1.8后的源码

其中HashMap的部分变量成员先列出来

//一个Node型的table数组指针 transient Node<K,V>[] table; //Node结点类 static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; V value; Node<K,V> next; Node(int hash, K key, V value, Node<K,V> next) { this.hash = hash; this.key = key; this.value = value; this.next = next; } public final K getKey() { return key; } public final V getValue() { return value; } public final String toString() { return key + "=" + value; } public final int hashCode() { return Objects.hashCode(key) ^ Objects.hashCode(value); } public final V setValue(V newValue) { V oldValue = value; value = newValue; return oldValue; } public final boolean equals(Object o) { if (o == this) return true; if (o instanceof Map.Entry) { Map.Entry<?,?> e = (Map.Entry<?,?>)o; if (Objects.equals(key, e.getKey()) && Objects.equals(value, e.getValue())) return true; } return false; } } 

咱进行源码的分析


HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
objectObjectHashMap.put(“1”, “1”);

首先进入HashMap的put方法

 public V put(K key, V value) { //	  hasn运算得出的hash值 || \/ return putVal(hash(key), key, value, false, true); } 

之后再进入这个 putVal方法中,看注释

 final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; //判断table数组的长度是否为0或者table指针是否为空,若条件为真,则将数组扩容为初始的16 if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; //这个地方进行table[通过上边得到的哈希值及table数组长度-1进行与运算得出的索引]是否为空的判断 if ((p = tab[i = (n - 1) & hash]) == null) //若为空,说明此处没有值,将node结点加入此处 tab[i] = newNode(hash, key, value, null); else { //否则即产生哈希冲突,。若key值内容相同则替换旧的value, //不然连接到链表后面,链表长度超过阈值8并且table长度大于64时就转换为红黑树存储。 Node<K,V> e; K k; if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) e = p; else if (p instanceof TreeNode) e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); else { for (int binCount = 0; ; ++binCount) { if ((e = p.next) == null) { p.next = newNode(hash, key, value, null); if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash); break; } if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } } if (e != null) { // existing mapping for key V oldValue = e.value; if (!onlyIfAbsent || oldValue == null) e.value = value; afterNodeAccess(e); return oldValue; } } ++modCount; if (++size > threshold) resize(); afterNodeInsertion(evict); return null; } 

本文地址:https://blog.csdn.net/qq_44643051/article/details/107897472