HashMap的实现原理,以及在JDK1.7和1.8的区别
1.JDK1.7
HashMap是Java中大家最常用的一个map实现类,其为键值对也就是key-value的形式。他的数据结构则是采用的位桶和链表相结合的形式完成了,即拉链法。具体如下图所示:
HashMap里面存储的是静态内部类Entry的对象,这个对象其实也是一个key-value的结构。以下是Entry的源码:
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
/** 指向下一个元素的引用 */
Entry<K,V> next;
int hash;
/**
* 构造方法为Entry赋值
*/
Entry(int h, K k, V v, Entry<K,V> n) {
value = v;
next = n;
key = k;
hash = h;
}
...
...
}
1.1、HashMap的存取过程
// 存储时:
int hash = key.hashCode(); // 1个key对应一个固定的hash值
int index = hash % Entry[].length;
Entry[index] = value;
// 取值时:
int hash = key.hashCode();
int index = hash % Entry[].length;
return Entry[index];
如果两个key通过int index = hash % Entry[].length得到了相同的index,就会跟在之间那个entry连接在后面,也就是按照顺序存储在后面的链表中,也就是解决hash冲突的拉链法。
1.2、HashMap的get() 方法
由于可能会出现的Hash冲突,所以java采用了链地址法来处理冲突,首先会通过hashcode来查到对应的Entry对象,如果找到了之后发现这个链表上链接了多个Entry对象,则再调用equals方法对value进行逐一比较。但是如果当链表过长后,HashMap就会自动将链表转化为红黑树,以提高查找效率。
当链表数组的容量超过初始长度的0.75之后,再散列就会将该链表再扩大2倍,创建一个新的2倍长的链表,然后再讲数据逐个搬迁复制到新链表中去。
1.3、扩容时调用resize()
其默认的大小是16,一旦>0.75*16之后,就会调用resize()进行扩容,扩容非常耗时,所以如果需要保存较多的话,最好在创建一开始就制定好HashMap的初始容量。
2.JDK1.8
采用的是位桶数组,其底层采用红黑树。
- transient Node<k,v>[] table;//存储(位桶)的数组</k,v>
默认的加载因子是0.75,如果不扩容,链表就会越来越长,查找起来因为要逐一equals进行比对,所以会慢很多。当然现在因为又采用了红黑树,相对来说比jdk1.7要好一些。扩容之后,会将原本的链表数组中的每个链表分为奇偶两个,分别挂在新链表的数组下的对应的散列位置。减少查找时间,提高效率。
2.1 jdk1.8的最大区别就在于底层的红黑树策略。
相对于JDK1.7,
HashMap处理hash冲突时,会首先存放在链表中去,
但是一旦链表中的数据较多(即>8个)之后,就会转用红黑树来进行存储,优化存储速度。
红黑树O(lgn)。如果是链表。一定是O(n)。
HashMap的实现原理,以及在JDK1.7和1.8的区别的更多相关文章
- Java中HashMap底层实现原理(JDK1.8)源码分析
这几天学习了HashMap的底层实现,但是发现好几个版本的,代码不一,而且看了Android包的HashMap和JDK中的HashMap的也不是一样,原来他们没有指定JDK版本,很多文章都是旧版本JD ...
- HashMap底层实现原理(JDK1.8)源码分析
ref:https://blog.csdn.net/tuke_tuke/article/details/51588156 http://www.cnblogs.com/xiaolovewei/p/79 ...
- 牛客网Java刷题知识点之HashMap的实现原理、HashMap的存储结构、HashMap在JDK1.6、JDK1.7、JDK1.8之间的差异以及带来的性能影响
不多说,直接上干货! 福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号: 大数据躺过的坑 Java从入门到架构师 人工智能躺过的坑 ...
- HashMap的底层原理(jdk1.7.0_79)
前言 在Java中我们最常用的集合类毫无疑问就是Map,其中HashMap作为Map最重要的实现类在我们代码中出现的评率也是很高的. 我们对HashMap最常用的操作就是put和get了,那么你知道它 ...
- Java面试必问之Hashmap底层实现原理(JDK1.8)
1. 前言 上一篇从源码方面了解了JDK1.7中Hashmap的实现原理,可以看到其源码相对还是比较简单的.本篇笔者和大家一起学习下JDK1.8下Hashmap的实现.JDK1.8中对Hashmap做 ...
- Java面试必问之Hashmap底层实现原理(JDK1.7)
1. 前言 Hashmap可以说是Java面试必问的,一般的面试题会问: Hashmap有哪些特性? Hashmap底层实现原理(get\put\resize) Hashmap怎么解决hash冲突? ...
- HashMap 实现及原理
1.为什么用HashMap? HashMap是一个散列桶(数组和链表),它存储的内容是键值对(key-value)映射HashMap采用了数组和链表的数据结构,能在查询和修改方便继承了数组的线性查找和 ...
- 一文搞定HashMap的实现原理和面试
原文 https://juejin.im/post/5d09f2d56fb9a07ec7551fb0 HashMap在日常开发中基本是天天见的,而且都知道什么时候需要用HashMap,根据Key存取 ...
- 必懂知识——HashMap的实现原理
HashMap的底层数据结构 1.7之前是:数组+链表 数组的元素是Map.Entiry对象 当出现哈希碰撞的时候,使用链表解决, 先计算出key对应的数组的下标,这个数组的这个位置上为空,直接放入, ...
随机推荐
- 一个简易的allocator
#include <vector> #include <iostream> #include <algorithm> using namespace::std; t ...
- windows Jenkins git 配置
待更新 插件下载地址:http://updates.jenkins-ci.org/download/plugins/ 参考地址:https://blog.csdn.net/zzy1078689276/ ...
- 最短路,dijstra算法
#include<iostream> #include<stdio.h> #include<math.h> #include<vector> using ...
- FreeSWITCH添加中文语音
1.准备中文语音包 可以到freeswitch官网下载,也可以自己录制 2.中文资源的安装路径: 英文资源的路径为conf/sounds/en/us/callie/... 类似的设置中文资源的路径 ...
- jdbc “贾琏欲执事”
“贾琏欲执事” 1.加载驱动2.获取连接3.SQL语句4.执行SQL5.释放资源 示例: public void test_insert() { String driver="oracle. ...
- CSS-精灵图片的使用(从一张图片中截图指定位置图标)
一.名词解释 在网页中,我们可以看到有很多的小图标,比如微博上的登录位置有很多这样的小图标.因为浏览器显示网页的所有内容都需要从我们自己的服务器进行下载,如果将这些图标分别存在服务器上,那么当需要 ...
- supervisord.conf
; Sample supervisor config file.;; For more information on the config file, please see:; http://supe ...
- Date.parse()转化日期为时间戳,ios与Android兼容写法
把固定格式日期转化为时间戳: //格式化当地日期 new Date('2017-11-11 0:0:0') //结果为:Sat Nov 11 2017 00:00:00 GMT+0800 (中国标准时 ...
- 内存溢出eclipse启动tomcat
1.在eclipse中的Window->preferences->Java->install jar->选择JDK,然后在点击Edit,在Default VM argument ...
- [ Codeforces Round #549 (Div. 2)][D. The Beatles][exgcd]
https://codeforces.com/contest/1143/problem/D D. The Beatles time limit per test 1 second memory lim ...