【Java集合】JDK1.7和1.8 HashMap有什么区别
JDK1.7和1.8 HashMap区别:
1.数组+链表改成了数组+链表或红黑树;
2.表的插入方式从头插法改成了尾插法,简单说就是插入时,如果数组位置上已经有元素,1.7将新元素放到数组中,原始节点作为新节点的后继节点,1.8遍历链表,将元素放置到链表的最后;
3.在插入时,1.7先判断是否需要扩容,再插入,1.8先进行插入,插入完成再判断是否需要扩容
4.扩容的时候1.7需要对原数组中的元素进行重新hash定位在新数组的位置,1.8采用更简单的判断逻辑,位置不变或索引+旧容量大小;
原因:
1.防止发生hash冲突,链表长度过长,将时间复杂度由O(n)
降为O(logn)
;
2.因为1.7头插法扩容时,头插法会使链表发生反转,多线程环境下会产生环;
A线程在插入节点B,B线程也在插入,遇到容量不够开始扩容,重新hash,放置元素,采用头插法,后遍历到的B节点放入了头部,这样形成了环,如下图所示:
1.7的扩容调用transfer代码,如下所示:
void transfer(Entry[] newTable, boolean rehash) {
int newCapacity = newTable.length;
for (Entry<K,V> e : table) {
while(null != e) {
Entry<K,V> next = e.next;
if (rehash) {
e.hash = null == e.key ? 0 : hash(e.key);
}
int i = indexFor(e.hash, newCapacity);
e.next = newTable[i]; //A线程如果执行到这一行挂起,B线程开始进行扩容
newTable[i] = e;
e = next;
}
}
}
3.扩容的时候为什么1.8 不用重新hash就可以直接定位原节点在新数据的位置呢?
这是由于扩容是扩大为原数组大小的2倍,用于计算数组位置的掩码仅仅只是高位多了一个1,怎么理解呢?
扩容前长度为16,用于计算(n-1) & hash 的二进制n-1为0000 1111,扩容为32后的二进制就高位多了1,为0001 1111。
因为是& 运算,1和任何数 & 都是它本身,那就分二种情况,如下图:原数据hashcode高位第4位为0和高位为1的情况;
第四位高位为0,重新hash数值不变,第四位为1,重新hash数值比原来大16(旧数组的容量)
参考博客:
【Java集合】JDK1.7和1.8 HashMap有什么区别的更多相关文章
- Java 集合系列14之 Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等使用场景)
概要 学完了Map的全部内容,我们再回头开开Map的框架图. 本章内容包括:第1部分 Map概括第2部分 HashMap和Hashtable异同第3部分 HashMap和WeakHashMap异同 转 ...
- Java 集合 JDK1.7的LinkedList
Java 集合 JDK1.7的LinkedList @author ixenos LinkedList LinkedList是List接口的双向链表实现,JDK1.7以前是双向循环链表,以后是双向非循 ...
- java集合框架(一):HashMap
有大半年没有写博客了,虽然一直有在看书学习,但现在回过来看读书基本都是一种知识“输入”,很多时候是水过无痕.而知识的“输出”会逼着自己去找出没有掌握或者了解不深刻的东西,你要把一个知识点表达出来,自己 ...
- java集合学习(2):Map和HashMap
Map接口 java.util 中的集合类包含 Java 中某些最常用的类.最常用的集合类是 List 和 Map. Map 是一种键-值对(key-value)集合,Map 集合中的每一个元素都包含 ...
- java集合初探(一):HashMap.
一.概述 HashMap可能是我们最经常用的Map接口的实现了.话不多说,我们先看看HashMap类的注释: 基于哈希表的Map接口实现. 这个实现提供了所有可选的映射操作,并允许空值和空键.(Has ...
- java 集合及其线程安全 及其 set linkedList map table 区别
早在jdk的1.1版本中,所有的集合都是线程安全的.但是在1.2以及之后的版本中就出现了一些线程不安全的集合,为什么版本升级会出现一些线程不安全的集合呢?因为线程不安全的集合普遍比线程安全的集合效率高 ...
- Java 集合系列10之 HashMap详细介绍(源码解析)和使用示例
概要 这一章,我们对HashMap进行学习.我们先对HashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用HashMap.内容包括:第1部分 HashMap介绍第2部分 HashMa ...
- Java集合框架:HashMap
转载: Java集合框架:HashMap Java集合框架概述 Java集合框架无论是在工作.学习.面试中都会经常涉及到,相信各位也并不陌生,其强大也不用多说,博主最近翻阅java集合框架的源码以 ...
- 1.Java集合-HashMap实现原理及源码分析
哈希表(Hash Table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理也常常 ...
随机推荐
- while、do...while和for循环
一.循环 1.1 定义 当满足一定条件的时候,重复执行某一段代码的操作 while和for和do...while是java中的循环 二.while循环 2.1 定义 int i = 0: 初始化值 w ...
- 微信小程序封装请求接口
var rootDocment = 'https://123.com';//你的域名 function postData(url, data, cb) { wx.request({ url: root ...
- CCF(引水入城:60分):最大流+ISAP算法
引水入城 201703-5 这从题目分析来看很像最大流的问题,只需要增加一个超级源点和一个超级汇点就可以按照题意连边再跑最大流算法. 因为数据量太大了,肯定会超时.但是没有想到可行的解决方法. #in ...
- EurekaServer源码分析
Eureka Server功能 接受服务注册 接受服务心跳 服务剔除 服务下线 集群同步 获取注册表中服务实例信息 需要注意的是,Eureka Server同时也是一个Eureka Client,在不 ...
- crudapi零代码开发平台应用场景和成功案例
应用场景 在前面文章中,已经介绍了crudapi主要功能和使用方式,本文主要介绍crudapi应用场景以及具体的使用方式. 概要 crudapi属于产品级的零代码平台,无需编程,通过配置自动生成cru ...
- docker在vulhub中的使用命令合集
(1)docker ps(查询 docker 进程的所有容器) (2)docker info(查看docker详细信息) (3)service docker start(启动docke ...
- .Net Core 2.1 升级3.1 问题整理
随着技术的不断拓展更新,我们所使用的技术也在不断地升级优化,项目的框架也在不断地升级,本次讲解 .net core 2.1 升级到3.1所需要注意的事项: 当项目框架升级后,所有的Nuget引用也会 ...
- 自己挖的坑自己填--Mybatis mapper文件if标签中number类型及String类型的坑
1.现象描述 (1)使用 Mybatis 在进行数据更新时,大部分时候update语句都需要通过动态SQL进行拼接.在其中,if标签中经常会有 xxx !='' 这种判断,若 number 类型的字段 ...
- drozer使用总结
adb forward tcp:31415 tcp:31415 drozer console connect run app.package.list -f baidu 查看包名 run a ...
- python mac地址计算
思路是10/16进制的转换和字符串的处理 开始造轮子 1.判断是否是mac地址 正则匹配是否符合条件 1 import re 2 3 def isMac(string): 4 preg = re.co ...