Java中HashMap等的实现要点浅析
@南柯梦博客中的系列文章对Jdk中常用容器类ArrayList、LinkedList、HashMap、HashSet等的实现原理以代码注释的方式给予了说明(详见http://www.cnblogs.com/dongying/p/4022795.html#3045118等文章),而我在这里用另一种方式对其实现要点作一说明。
一、ArrayList和LinkedList的实现
ArrayList和LinkList的实现原理比较简单,在关于Java的面试中经常被要求立即写出这两种容器类的简单实现。正如其名称所显示的,利用Java对泛型的支持在内部分别使用数组和双向链表存储元素,当容量不足时进行扩容,因而这两种容器类的适用场景基本对应于数组和链表的适用场景。
二、HashMap的实现之hash值
HashMap的实现使用了内部类Entry,实际上存储在HashMap中的键值对就是使用Entry类型的数组来存储的,而Entry同时还是个单向无头链表,其用next属性指向下一个元素。存储键值对时首先得到key的hash值,并计算其在Entry数组中的存储位置,如方法indexFor所示:
static int indexFor(int h, int length) {
return h & (length-1);
}
即将hash值和Entry数组做按位与运算得到其应存储的位置索引。接下来的处理就是其中的精华了。如果该位置处是空的,则把代表键值对的Entry对象放入;否则位置处存在Entry链表,遍历该链表,如果有Entry节点的key值和待插入的Entry对象相等,则用新的value值替换旧值并返回旧值;如果没有相等的key值则把新的Entry对象放到链表头处。
三、相同hash值时键值对的存储结构
总结一下,实际上这是不同key的hash值相同时的冲突处理方法。根据hash值的原理,相同元素其hash值必定相同,不同元素其hash值不一定相同。反过来讲,hash值相同的元素其值不一定相同,但hash值不同的元素其值一定不同。因此不同元素根据hash值以及indexFor()方法取得的索引值很可能是相同的,故需要在索引位置处用链表存储所有元素以供进一步甄别。由此可以推断出,HashMap的get()方法只能保证近似的O(1)时间复杂度。HashMap中的loadFactor属性也正是因为这个原因才存在的。进一步查看源码发现,Jdk8中HashMap的实现已有所变化,相同hash值的键值对是用链表和红黑树来共同实现的,具体使用哪种结构由冲突的key值个数决定。这样查找的时间复杂度得到了进一步优化,但同时增加了存储的时间,因为要涉及链表和红黑树的转换以及红黑树的再平衡等。
三、HashMap应用之HashSet
而对于HashSet可以看做HashMap的一种特殊的使用,即对HashMap中所有的key值都存储相同的外部不可见的对象。
Java中HashMap等的实现要点浅析的更多相关文章
- Java中HashMap遍历的两种方式
Java中HashMap遍历的两种方式 转]Java中HashMap遍历的两种方式原文地址: http://www.javaweb.cc/language/java/032291.shtml 第一种: ...
- 【转】 java中HashMap详解
原文网址:http://blog.csdn.net/caihaijiang/article/details/6280251 java中HashMap详解 HashMap 和 HashSet 是 Jav ...
- java中HashMap详解(转)
java中HashMap详解 博客分类: JavaSE Java算法JDK编程生活 HashMap 和 HashSet 是 Java Collection Framework 的两个重要成 ...
- java集合(2)- java中HashMap详解
java中HashMap详解 基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了非同步和允许使用 null 之外,HashMap 类与 H ...
- Java中HashMap的实现原理
最近面试中被问及Java中HashMap的原理,瞬间无言以对,因此痛定思痛觉得研究一番. 一.Java中的hashCode和equals 1.关于hashCode hashCode的存在主要是用于查找 ...
- JAVA中hashmap的分析
从http://blog.csdn.net/luanlouis/article/details/41576373?utm_source=tuicool&utm_medium=referral学 ...
- JAVA中HashMap相关知识的总结(一)
Java中HashMap在jdk1.7和jdk1.8中的区别点: 在jdk1.7中是用数组+链表形式存储,1.8采用数组+链表/红黑树形式 Jdk1.8中由链表转为红黑树是长度大于8,由红黑树转为链表 ...
- java中HashMap的设计精妙在哪?
摘要:本文结合图解和问题,教你一次性搞定HashMap 本文分享自华为云社区<java中HashMap的设计精妙在哪?用图解和几个问题教你一次性搞定HashMap>,作者:breakDaw ...
- java中HashMap的用法
重点介绍HashMap.首先介绍一下什么是Map.在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value.在下文中会 ...
随机推荐
- 读《UNIX编程艺术》一感
我记得早在2006年的时候就开始频繁使用awk做文本处理方面的工作,07年的时候周围有人用perl,我还感到很不解,觉得写得很复杂,没有awk one liner 那么方便和神奇.一直在了解awk的具 ...
- XAF进修二:在XAF中打开自定义的WinForm
在建造WinForm时须要加上一机关函数和Show办法 using System; using System.Collections.Generic; using System.ComponentMo ...
- NOT IN查询效率低,用它的等效写法提高效率。
最近在处理大数据量导入的时候,使用OPENROWSET将Excel导入到临时表中之后,需要对数据进行唯一性验证.这时候发现使用NOT IN严重影响效率,一条sql可能执行10分钟甚至更久.尝试改变写法 ...
- C#设置字体(FontDIalog)、颜色(ColorDialog)对话框控件
设置字体控件为FontDialog,设置颜色的控件为ColorDialog.这两个控件的使用和OpenFileDialog(打开文件)及FolderBroswerDialog(打开文件夹)的使用类似. ...
- 使用guava进行对字符串的加锁
java的synchronized关键字是堆某对象加锁,但是我们当需要对某个字符串加锁怎么办 比如对同一个订单只能有一个操作,但是对其他订单的操作不影响 使用 guava包下的 Interner 类 ...
- 2-6 Working with Lambdas
在C++中使用匿名函数,格式如下:[] () {}; Using a Lambda to Print array Values #include <algorithm> #include ...
- tomcat(三)--基本安装配置
0x01 JDK和Tomcat安装 到oracle官网下载jdk,当前下载的版本是Linux x64 jdk-8u101-linux-x64.tar.gz 到apache官网下载tomcat,当前最 ...
- 「脑洞」图片转HTML(支持动画)
也许是受到很久以前看到的这玩意儿的原因:The Shapes of CSS 现在开脑洞写了个自动转换,顺便支持了动画……嗯,纯 CSS (:з」∠) 主要步骤就是用 Python 读图片,然后把像素全 ...
- HTML5 CSS3学习
HTML5 CSS3学习 :http://www.1000zhu.com/course/css3/ HTML5 相关书籍: http://www.html5cn.com.cn/news/gdt/2 ...
- c# htmtToPDF
http://www.cnblogs.com/shanyou/archive/2012/09/07/2676026.html