HashMap学习笔记
来源:互联网 发布:三国杀 知乎 编辑:程序博客网 时间:2024/06/06 21:40
关于HashMap的工作原理与实现的好文章不少,推荐几个:
http://blog.csdn.net/u010887744/article/details/50346257
http://yikun.github.io/2015/04/01/Java-HashMap工作原理及实现/
http://blog.csdn.net/vking_wang/article/details/14166593
对着HashMap的源码来看理解的会更好,JDK的版本不同具体的实现原理也有所不同,新版本都是在有所改进,减少碰撞,同时更少的rehash,这么做都是为了更高的效率和更少的bug。我是用jdk1.7学习的,jdk版本不是重点,重点对其中的原理理解即可。
1.实现
HashMap是采用数组+单向链表的方式实现的。这样做结合了数组寻址容易和链表插入删除快的有点。HashMap也可以理解为链表的数组,也是哈希表的一种实现方法-拉链法。在JDK8里,新增默认为8的閥值,当一个桶里的Entry超过閥值,就不以单向链表而以红黑树来存放以加快Key的查找速度。
2.原理
2.1 put,即HashMap.put(K,V)方法。
首先需要确认该数据元素在数组中位置。数组的默认长度是16(assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2";).
先用key计算h,然后用h和length-1按位与所得的值即为该数据数组在数组中的index(位置)。
k即为key
h ^= k.hashCode();h ^= (h >>> 20) ^ (h >>> 12);return h ^ (h >>> 7) ^ (h >>> 4);
return h & (length-1);//index,在数组中的位置
然后将该数据放在单向链表中。
Entry<K,V> e = table[bucketIndex];table[bucketIndex] = new Entry<>(hash, key, value, e);//此e为上一个单向链表的第一个元素
这句可以看出新元素是单向链表的第一个元素,并且指向上一个保存在该单向链表的第一个元素,这一过程称为碰撞(我的理解)。
resize
当多个key向HashMap中put的时候,碰撞就可能会变得频繁,可能某个单向链表会变得很长,get元素的时候查找效率就会降低。JDK中是这样解决的:
if ((size >= threshold) && (null != table[bucketIndex])) { resize(2 * table.length); hash = (null != key) ? hash(key) : 0; bucketIndex = indexFor(hash, table.length); }
threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
loadFactor初始值是0.75
threshold是阈值。初始值16*0.75=8.
Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); Object key = entry.getKey(); Object val = entry.getValue(); }
Iterator iter = map.keySet().iterator(); while (iter.hasNext()) { Object key = iter.next(); Object val = map.get(key); }
- Java学习笔记-HashMap
- HashMap源码学习笔记
- HashMap学习笔记
- HashMap学习笔记
- HashMap学习笔记
- HashMap学习笔记
- HashMap学习笔记
- HashMap源码学习笔记
- HashMap的学习笔记
- 学习笔记--实现HashMap
- Java学习笔记之HashMap
- HashMap学习笔记:put方法
- HashMap学习笔记:get方法
- HashMap与HashTable学习笔记
- HashMap和Hashtable的区别 ---学习笔记
- JAVA学习笔记7 Hashset ,TreeSet , HashMap
- poco库学习笔记(8) Poco::HashMap
- Java 学习笔记18:深入Java HashMap
- 递归的全排列(耗时比较长)
- 码农小汪-设计模式-模板方法
- 图像恢复技术之Matlab中的维纳滤波代码复现
- 一个大四求职菜鸟的web前端之路(终)
- C++ 中Traits技术 (3) —— 关于特化和偏特化
- HashMap学习笔记
- Qt学习记录--03 Qt的信号槽的使用
- 原生 js 实现全屏滚动效果
- LeetCode——034
- lintcode之最长公共前缀
- JavaWeb企业实训 简易股市自选查询分析系统(三)前端页面加入highchart及CSS3列表
- 易生活(一)-web---商品上传、smartupload使用、虚拟路径
- Hadoop学习
- 树莓派系统安装教程