hashMap.putIfAbsent( k, v) 下面,我们逐步分析put方法,以下方代码为例。public class Hash { public static void main(String[] args) { HashMap<String, Object> hashMap = new HashMap<>(); hashMap.put("yang", "123"); System.out.println(hashMap.size()); } } ...
HashMap的get方法是通过key获取对应Value的方法,resize方法则是初始化或扩容数组的方法,来看看是如何实现的; 1.get方法 通过getNode方法传入key的hash值与key,判断返回是否为空,空则返回null,否则返回key对应的value值; 方法中第一个if判断数组是否为空、数组长度是否大于0,并且通过(n-1)&hash计算出的下标在数组...
& 0111=0101即数组下标为5,说明hash为 T101的元素都落在table[5]上 即: newTab[j + oldCap]。
我们不妨先来看这段代码中的resize方法做了什么 下面是resize方法的部分源码,从注释就可以看出,是用来初始化或扩容数组的 那么显而易见,tab就是HashMap底层存储数据的数组。n就是tab数组的长度。hash是什么? put方法在调用putVal方法的时候,传参数时,调用了hash方法,下面是hash方法的源码 hash方法计算了key的hash值。
Java8.HashMap源码-resize()流程图 HashMap.resize() 链表扩容图解 Q1:如何理解扩容时(e.hash & oldCap) == 0? Q2:如何理解扩容时newTab[j + oldCap]? 设:HashMap.table = table[4] table[1]=X1->X2->X3->X4 1=X1.hash&(4-1)=X2.hash&(4-1)... 4-1=3->0011 若X.hash&0011 = 00...
6.HashMap 的扩容 resize() 原理 我们先来上一段测试代码,直观感受一下 HashMap 的真实的扩容过程: 代码语言:javascript 复制 package i import java.util.* /** * @author: Jack * 2020-03-21 21:55 */ fun main(args: Array<String>) { val map = HashMap<String, Int>(2) val clz = ...
4 resize方法 在上面putVal方法中的第39行和118行代码处,都是调用了resize方法来进行初始化或扩容的。而resize方法也是HashMap源码中比较精髓、比较有亮点的一个方法。其具体实现大致可以分为两部分:设置扩容标志位和具体的数据迁移过程。下面就首先来看一下resize方法的前半部分源码:上面在把newCap、newThr和...
插入数据分成了两张图,填上了对应的注释,hashmap是懒加载的,所以这首次添加数据就会涉及到扩容操作,扩容方法为resize()resize()扩容方法 分成了三张图 五、删除数据 删除数据和新增数据代码很像,这个会涉及到红黑树的数量过少时转链表的操作 六、清空容器 清空方法很简单,将哈希桶数据置为null,真实数据由gc...
n = (tab = resize()). length ; //根据hash值获取节点,为空就创建一个新的 if ((p = tab[i = (n - 1 ) & hash]) == null ) tab[i] = newNode(hash , key , value , null ) ; else { Node< K , V > e ; K k ;
4. Hashmap中get()过程 get()逻辑相对比较简单,如图所示 我们来对应下get()源码 5. Hashmap中resize()过程 只要是新插入元素,即执行addEntry()方法,在插入完成后,都会判断是否需要扩容。从addEntry()方法可知,扩容后的容量为原来的2倍。这里有个transfer()方法没讲,别着急,扩容时线程安全的问题出现在...