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值。
5. HashMap 的并发问题5.1 JDK 1.7 的并发问题并发扩容导致死循环(线程同时 resize())。 多线程同时插入数据,导致数据丢失。5.2 线程安全的替代方案ConcurrentHashMap:推荐使用,线程安全,性能高。 Collections.synchronizedMap(new HashMap<>()):使用同步包装类。
HashMap 需要放置 1024 个元素,由于没有设置容量初始大小,随着元素增加而被迫不断扩容, resize()方法总共会调用 8 次,反复重建哈希表和数据迁移。 当放置的集合元素个数达千万级时会影响程序性能。 注: 博客: 霸道流氓气质的博客_博客-C#,架构之路,SpringBoot领域博主 ...
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...
4 resize方法 在上面putVal方法中的第39行和118行代码处,都是调用了resize方法来进行初始化或扩容的。而resize方法也是HashMap源码中比较精髓、比较有亮点的一个方法。其具体实现大致可以分为两部分:设置扩容标志位和具体的数据迁移过程。下面就首先来看一下resize方法的前半部分源码:上面在把newCap、newThr和...
插入数据分成了两张图,填上了对应的注释,hashmap是懒加载的,所以这首次添加数据就会涉及到扩容操作,扩容方法为resize()resize()扩容方法 分成了三张图 五、删除数据 删除数据和新增数据代码很像,这个会涉及到红黑树的数量过少时转链表的操作 六、清空容器 清空方法很简单,将哈希桶数据置为null,真实数据由gc...