@南柯梦博客中的系列文章对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等的实现要点浅析的更多相关文章

  1. Java中HashMap遍历的两种方式

    Java中HashMap遍历的两种方式 转]Java中HashMap遍历的两种方式原文地址: http://www.javaweb.cc/language/java/032291.shtml 第一种: ...

  2. 【转】 java中HashMap详解

    原文网址:http://blog.csdn.net/caihaijiang/article/details/6280251 java中HashMap详解 HashMap 和 HashSet 是 Jav ...

  3. java中HashMap详解(转)

    java中HashMap详解 博客分类: JavaSE Java算法JDK编程生活       HashMap 和 HashSet 是 Java Collection Framework 的两个重要成 ...

  4. java集合(2)- java中HashMap详解

    java中HashMap详解 基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了非同步和允许使用 null 之外,HashMap 类与 H ...

  5. Java中HashMap的实现原理

    最近面试中被问及Java中HashMap的原理,瞬间无言以对,因此痛定思痛觉得研究一番. 一.Java中的hashCode和equals 1.关于hashCode hashCode的存在主要是用于查找 ...

  6. JAVA中hashmap的分析

    从http://blog.csdn.net/luanlouis/article/details/41576373?utm_source=tuicool&utm_medium=referral学 ...

  7. JAVA中HashMap相关知识的总结(一)

    Java中HashMap在jdk1.7和jdk1.8中的区别点: 在jdk1.7中是用数组+链表形式存储,1.8采用数组+链表/红黑树形式 Jdk1.8中由链表转为红黑树是长度大于8,由红黑树转为链表 ...

  8. java中HashMap的设计精妙在哪?

    摘要:本文结合图解和问题,教你一次性搞定HashMap 本文分享自华为云社区<java中HashMap的设计精妙在哪?用图解和几个问题教你一次性搞定HashMap>,作者:breakDaw ...

  9. java中HashMap的用法

    重点介绍HashMap.首先介绍一下什么是Map.在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value.在下文中会 ...

随机推荐

  1. SQL基本语句以及示例

    基本语句: /*dorp colunm*/ 语法:ALTER TABLE 表名   DROP COLUMN 要删除的字段 验证财务转换的正确性,查询以下两个表是否有数据 /*表连接inner jion ...

  2. POJ3061 尺取法

    题目大意:从给定序列里找出区间和大于等于S的最小区间的长度. 前阵子在zzuli OJ上见过类似的题,还好当时补题了.尺取法O(n) 的复杂度过掉的.尺取法:从头遍历,如果不满足条件,则将尺子尾 部增 ...

  3. SAP 采购订单行项目中科目分配被隐藏,发现行项目设置中显示字段长度为0

    1.sm30 维护 视图 TCVIEW 修改对应字段的显示长度

  4. nginx.conf详解

    ##定义nginx运行的用户各用户组user nginx nginx; ##nginx进程数,建议设置与cpu核心数一致worker_processes 1; #为每个进程分配CPU的工作内核 wor ...

  5. Tomcat单向Https验证搭建,亲自实现与主流浏览器、Android/iOS移动客户端安全通信

    众所周知,iOS9已经开始在联网方面默认强制使用Https替换原来的Http请求了,虽然Http和Https各有各的优势,但是总得来说,到了现在这个安全的信息时代,开发者已经离不开Https了. 网上 ...

  6. C++中虚继承派生类构造函数的正确写法

    最近工作中某个软件功能出现了退化,追查下来发现是一个类的成员变量没有被正确的初始化.这个问题与C++存在虚继承的情况下派生类构造函数的写法有关.在此说明一下错误发生的原因,希望对更多的人有帮助. 我们 ...

  7. Codeforces 738D. Sea Battle 模拟

    D. Sea Battle time limit per test: 1 second memory limit per test :256 megabytes input: standard inp ...

  8. Oracle 中的作业队列和队列调度

    一,启动执行作业的进程       在 Oracle 中,是使用 “作业队列协调进程(CJQ0)” 这个协调数据库实例的作业队列的后台进程,来监视作业队列中的作业表(JOB$),并启动作业队列进程(J ...

  9. XE3随笔21:系统默认语言与系统支持的语言列表

    unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, For ...

  10. HttpWebResponse远程服务器返回错误: (500) 内部服务器错误。

    现象 我们编码实现请求一个页面时,请求的代码类似如下代码: HttpWebRequest req = (HttpWebRequest)WebRequest.Create(strUrl); req.Us ...