java——HashMap的实现原理,自己实现简单的HashMap
数据结构中有数组和链表来实现对数据的存储,但是数组存储区间是连续的,寻址容易,插入和删除困难;而链表的空间是离散的,因此寻址困难,插入和删除容易。
因此,综合了二者的优势,我们可以设计一种数据结构——哈希表(hash table),它寻址、插入和删除都很方便。在java中,哈希表的实现主要就是HashMap了,可以说HashMap是java开发中使用最多的类之一吧。
HashMap的底层其实就是链表的数组,代码为
transient Entry[] table;
这里的table其实就是一个链表的数组,因为我们的数据是二元的,因此HashMap定义了一个内部的类Entry,它包含了key和value两个属性。这样一个一维的线性数组就可以存储两个值了。同时Entry是一个链表,因此还有一个Entry next属性,它指向了下一个节点。
存储put时:
首先计算出key的hash,然后用table[hash]得到那个链表,再遍历这个链表,如果链表中有一个key和这个key是满足equals的话,则将value替换掉;如果没有的话,则插入到链表的尾部。
int h = hash(key); Entry e = table[h];
for (Entry<K,V> e = table[i]; e != null; e = e.next) {Object k;//如果key在链表中已存在,则替换为新valueif (e.hash == hash && ((k = e.key) == key || key.equals(k))) {V oldValue = e.value;e.value = value;e.recordAccess(this);return oldValue;}}
在get时,也是以同样的方法得到那个链表Entry e;然后遍历这个链表取出元素
for (Entry<K,V> e = table[indexFor(hash, table.length)];e != null;e = e.next) {Object k;if (e.hash == hash && ((k = e.key) == key || key.equals(k)))return e.value;}return null;
HashMap对性能的优化:
HashMap对性能优化,主要是在于减少hash冲突(不同的key算出同样的hash),因为hash冲突越多,从链表中需要的寻址时间就越长。
1.通过计算hash值的方式减少hash冲突:
这个hash方法有效的减少了hash冲突:(具体我确实不懂!大家参考http://zhangshixi.iteye.com/blog/672697)
static int hash(int h) { h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); } static int indexFor(int h, int length) { return h & (length-1); }
我自己写了一个非常简单计算hash值的方式,勉强能用:
Math.abs(o==null?0:o.hashCode()) % length
2.自动扩容
当HashMap中的元素越来越多的时候,hash冲突的几率也就越来越高,因为数组的长度是固定的。因此,此时就需要对数组进行扩容了。
当HashMap中的元素个数超过数组大小*loadFactor(默认值0.75)时,就会进行数组扩容。这时,需要创建一张新表,将原表的映射到新表中。
扩容时,遍历每个元素,重新计算其hash值,然后加入新表中。
一般来说,扩容数组的大小为原数组大小的两倍。而这是一个很耗性能的操作,因此,如果我们已经预知HashMap中元素的个数,那么提前设置初始容量将大大提升其性能。
我将我的源码放到了github上,欢迎大家下载交流。
http://pan.baidu.com/s/1qXN137Q (12月19号更新)
https://github.com/xcr1234/my-java
附上自己实现的性能测试结果,勉强能接受
这篇博文和代码肯定还有很多不足的地方,也请各位大神指出!或者fork我的代码并提出宝贵的建议,谢谢!
转载于:https://www.cnblogs.com/xcr1234/p/6187663.html
java——HashMap的实现原理,自己实现简单的HashMap相关推荐
- java台球游戏设计原理_Java实现简单台球游戏
Java实现简单台球桌问题,供大家参考,具体内容如下 需求: 使小球可以在桌面上移动,移动到桌面边缘将被弹回,显示小区的移动 素材: 小球照片 桌球照片 程序源代码: package 桌球游戏; im ...
- HashMap的工作原理
HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此 ...
- HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别
Hash算法 Hash,一般翻译做"散列",也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的 ...
- HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别(转)
HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别 文章来源:http://www.cnblogs.com/beatIteWeNerverGiveU ...
- HashMap的工作原理及其相关的知识点
2019独角兽企业重金招聘Python工程师标准>>> 先来些简单的问题 "你用过HashMap吗?" "什么是HashMap?你为什么用到它?&quo ...
- HashMap的工作原理--重点----数据结构示意图的理解
HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道HashTable和HashMap之间的区别,那么为何这道面试题如此 ...
- 阿里P7级别架构师教你HashMap的工作原理
HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此 ...
- HashMap底层实现原理及面试问题
一.HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算 ...
- Java面试绕不开的问题: Java中HashMap底层实现原理(JDK1.8)源码分析
这几天学习了HashMap的底层实现,但是发现好几个版本的,代码不一,而且看了Android包的HashMap和JDK中的HashMap的也不是一样,原来他们没有指定JDK版本,很多文章都是旧版本JD ...
- Java HashMap的实现原理详解
HashMap是Java Map类型的集合类中最常使用的,本文基于Java1.8,对于HashMap的实现原理做一下详细讲解. (Java1.8源码:http://docs.oracle.com/ja ...
最新文章
- 字符串操作系列库函数
- 类: property
- 解决Mac安装tesserocr报错问题 Failed building wheel for
- 微信小程序AES加密解密
- mongdb 群集_群集文档的文本摘要
- OpenCV中基本数据结构(3)_Size
- Android-Parcelable理解与使用(对象序列化)
- Codeforces Round 253 (Div. 2)
- Linux系统编程(28)——线程间同步
- 中国湖北区域汉至现代行政区划GIS数据
- 《未来简史》读书笔记
- 如何注册海外邮箱?如何进行邮箱注册163,这些技巧交给你
- PBR 前言 颜色理论:色度、色域与色彩空间
- 笔记本电脑f11功能键_电脑技巧:键盘上F功能键F1-F12详解
- 基于python的opencv计算机视觉基础知识及例程代码【视觉入门看这一篇就够了】
- NOIP2017翻车记
- ppt密码忘了怎么解除,ppt权限密码怎么解开?
- 微积分的历史(二):起源之牛顿
- VIJOS-P1232核电站问题
- AMBA之AHB总线
热门文章
- com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'test'
- WinForm ListView
- 《软件架构师的12项修炼》读书笔记-技术之天花板
- Delphi 计算儒略日(Julian day)的代码
- Python自动化开发学习22-Django上
- MongoDB(课时30 $group)
- 带你全面了解QinQ
- 10. Firewalls (防火墙 2个)
- 【高并发解决方案】6、数据库水平切分的实现原理解析
- Kuskal/Prim POJ 1789 Truck History