数据结构中有数组和链表来实现对数据的存储,但是数组存储区间是连续的,寻址容易,插入和删除困难;而链表的空间是离散的,因此寻址困难,插入和删除容易。

因此,综合了二者的优势,我们可以设计一种数据结构——哈希表(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相关推荐

  1. java台球游戏设计原理_Java实现简单台球游戏

    Java实现简单台球桌问题,供大家参考,具体内容如下 需求: 使小球可以在桌面上移动,移动到桌面边缘将被弹回,显示小区的移动 素材: 小球照片 桌球照片 程序源代码: package 桌球游戏; im ...

  2. HashMap的工作原理

    HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此 ...

  3. HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别

    Hash算法 Hash,一般翻译做"散列",也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的 ...

  4. HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别(转)

    HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别 文章来源:http://www.cnblogs.com/beatIteWeNerverGiveU ...

  5. HashMap的工作原理及其相关的知识点

    2019独角兽企业重金招聘Python工程师标准>>> 先来些简单的问题 "你用过HashMap吗?" "什么是HashMap?你为什么用到它?&quo ...

  6. HashMap的工作原理--重点----数据结构示意图的理解

    HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道HashTable和HashMap之间的区别,那么为何这道面试题如此 ...

  7. 阿里P7级别架构师教你HashMap的工作原理

    HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此 ...

  8. HashMap底层实现原理及面试问题

    一.HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算 ...

  9. Java面试绕不开的问题: Java中HashMap底层实现原理(JDK1.8)源码分析

    这几天学习了HashMap的底层实现,但是发现好几个版本的,代码不一,而且看了Android包的HashMap和JDK中的HashMap的也不是一样,原来他们没有指定JDK版本,很多文章都是旧版本JD ...

  10. Java HashMap的实现原理详解

    HashMap是Java Map类型的集合类中最常使用的,本文基于Java1.8,对于HashMap的实现原理做一下详细讲解. (Java1.8源码:http://docs.oracle.com/ja ...

最新文章

  1. 字符串操作系列库函数
  2. 类: property
  3. 解决Mac安装tesserocr报错问题 Failed building wheel for
  4. 微信小程序AES加密解密
  5. mongdb 群集_群集文档的文本摘要
  6. OpenCV中基本数据结构(3)_Size
  7. Android-Parcelable理解与使用(对象序列化)
  8. Codeforces Round 253 (Div. 2)
  9. Linux系统编程(28)——线程间同步
  10. 中国湖北区域汉至现代行政区划GIS数据
  11. 《未来简史》读书笔记
  12. 如何注册海外邮箱?如何进行邮箱注册163,这些技巧交给你
  13. PBR 前言 颜色理论:色度、色域与色彩空间
  14. 笔记本电脑f11功能键_电脑技巧:键盘上F功能键F1-F12详解
  15. 基于python的opencv计算机视觉基础知识及例程代码【视觉入门看这一篇就够了】
  16. NOIP2017翻车记
  17. ppt密码忘了怎么解除,ppt权限密码怎么解开?
  18. 微积分的历史(二):起源之牛顿
  19. VIJOS-P1232核电站问题
  20. AMBA之AHB总线

热门文章

  1. com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'test'
  2. WinForm ListView
  3. 《软件架构师的12项修炼》读书笔记-技术之天花板
  4. Delphi 计算儒略日(Julian day)的代码
  5. Python自动化开发学习22-Django上
  6. MongoDB(课时30 $group)
  7. 带你全面了解QinQ
  8. 10. Firewalls (防火墙 2个)
  9. 【高并发解决方案】6、数据库水平切分的实现原理解析
  10. Kuskal/Prim POJ 1789 Truck History