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.在下文中会 ...
随机推荐
- codeforces Codeforces Round #380 (Div. 1, Rated, Based on Technocup 2017 - Elimination Round 2)// 二分的题目硬生生想出来ON的算法
A. Road to Cinema 很明显满足二分性质的题目. 题意:某人在起点处,到终点的距离为s. 汽车租赁公司提供n中车型,每种车型有属性ci(租车费用),vi(油箱容量). 车子有两种前进方式 ...
- oracle 脱敏和加密
脱敏:在此只是对数据如姓名,身份证号码等进行简单粗暴的脱敏,即改变数据 针对于number类型的数据:update table_name set conlunm_name = substr (co ...
- JS中变量名作为if条件的 true/flase
在Javascript中,可以直接将变量名放到if条件中, var a;//甚至不定义 if (a){ //... } 以下情况被认为是flase: 1.''空的字符串 2.数字0 3.对象null ...
- sap 常用表
MM 表名 EBAN 采购申请
- 合并两个排好序的链表(c++)
#include<iostream> struct node{ int payload; node* next; node(int payload){this->payload=pa ...
- 使用dom元素和jquery元素实现简单增删改的练习
软件开发实际就是数据的增删改查,javascript前端开发也不例外.今天学了jquery框架的简单使用.于是用它实现简单的增删改,接着也用原始的javascript实现同样的功能,以便看出jquer ...
- Firefox每次刷新时自动清空缓存的设置方法
当我们开发网页应用时候,为了保证每次看到的页面是最新的,需要在刷新页面时清除页面缓存. 如果每次都手动清除比较麻烦,好在多数浏览器都支持自动清除缓存的功能. IE下我们可以将缓存设置为"每次 ...
- spring mvc(1):基础入门
依赖 pom.xml ( maven ) <properties> <spring.version>3.0.5.RELEASE</spring.version> ...
- 使用cookie实现计数器功能
思路是:若第一次访问,创建cookie.若访问次数大于一,则先读出cookie值赋给一个值,然后再重新写入cookie. <?php if(!isset($_COOKIE['num'])){ $ ...
- python os模块
import os path = "路径" os.getcwd() #获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname" ...