HashMap-JDK源码阅读

HashMap 结合数组的快速查询和链表的快速插入等优点实现。

参数说明:

  table:数组长度。

  size:k-v数量。

  modCount:结构改变标记,主要在并发环境下HashMap发生扩容等结构变化时校验,迭代时如果不及预期则抛出异常ConcurrentModificationException,而不是迭代完后再做校验。

  lodaFactor:加载因子,表示k-v在hashMap的密度。默认0.75,是一个对空间时间的权衡值,需求时间减少,需求空间增加。

  capacity:数组长度,初始值16;

  threshold:resize vlaue

put操作:

  1. 取得hashCode()。
  2. 高16位异或低16位,计算hash值。
  3. 如果篮子里面值为空hash值未发生碰撞,则直接放到篮子里。
  4. 如果hash值发生碰撞则迭代链表equals key值。
  5. 比较头节点如果相同就替换。
  6. 头节点不相同如果是否是红黑树则putTreeVal。
  7. 如果有key则替换v。
  8. 如果没有key则挂在后面。
  9. 如果链表长度等于大于等于8就把链表转成红黑树。
  10. 如果size大于threshold,扩容为原来的2倍。

set操作:

  1. 取得hash值
  2. 通过数组查找第一。
  3. 找不到再迭代后面的链表。

几个精妙的算法:

tableSizeFor(int cap),计算大于cap的最小的2的平方。从二进制的角度进行无符号右移操作得到最接近大于这个数的0x....11111,然后+1。

resize(),从二进制的角度,让原值均匀的分布在原位置或者原位置移动原长度的位置(2的幂),扩容后由于长度是原来的两倍,数组下标的hash会增加1位,通过&运算多查看一位hash,如果为0则说明在原位,如果为一说明在原位置移动原数组长度的位置,这就是数组长度用2次幂的好处之一,简直是精妙,省去了重新计算hash的操作,并发在这里会出现死链。

http://www.importnew.com/20386.html  

时间: 2024-08-05 09:36:09

HashMap-JDK源码阅读的相关文章

jdk源码阅读-HashMap

前置阅读: jdk源码阅读-Map : http://www.cnblogs.com/ccode/p/4645683.html 在前置阅读的文章里,已经提到HashMap是基于Hash表实现的,所以在讲解HashMap之前 ,有必要提前了解下Hash的原理. 参考<算法导论><算法>

JDK源码阅读(一):Object源码分析

最近经过某大佬的建议准备阅读一下JDK的源码来提升一下自己 所以开始写JDK源码分析的文章 阅读JDK版本为1.8 目录 Object结构图 构造器 equals 方法 getClass 方法 hashCode 方法 toString 方法 finalize 方法 registerNatives 方法 1. Object结构图 2. 类构造器 ??类构造器是创建Java对象的方法之一.一般我们都使用new关键字来进行实例,还可以在构造器中进行相应的初始化操作. ??在一个Java类中必须存在一个

JDK 源码 阅读 - 2 - 设计模式 - 创建型模式

A.创建型模式 抽象工厂(Abstract Factory) javax.xml.parsers.DocumentBuilderFactory DocumentBuilderFactory通过FactoryFinder实例化具体的Factory. 使用例子: DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docBuilder

jdk源码阅读笔记之java集合框架(二)(ArrayList)

关于ArrayList的分析,会从且仅从其添加(add)与删除(remove)方法入手. ArrayList类定义: p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Monaco } span.s1 { color: #931a68 } public class ArrayList<E> extends AbstractList<E> implements List<E> ArrayList基本属性: /** *

JDK源码阅读(三):ArraryList源码解析

今天来看一下ArrayList的源码 目录 介绍 继承结构 属性 构造方法 add方法 remove方法 修改方法 获取元素 size()方法 isEmpty方法 clear方法 循环数组 1.介绍 一般来讲文章开始应该先介绍一下说下简介.这里就不介绍了 如果你不知道ArrayList是什么的话就没必要在看了.大致讲一下一些常用的方法 2.继承结构 ArrayList源码定义: ArrayList继承结构如下: Serializable 序列化接口 Cloneable 前面我们在看Object源

jdk源码阅读笔记之java集合框架(一)(基础篇)

结合<jdk源码>与<thinking in java>,对java集合框架做一些简要分析(本着实用主义,精简主义,遂只会挑出个人认为是高潮的部分). 先上一张java集合框架的简图: 会从以下几个方面来进行分析: java 数组; ArrayList,LinkedList与Vector; HashMap; HashSet 关于数组array: 数组的解释是:存储固定大小的同类型元素.由于是"固定大小",所以对于未知数目的元素存储就显得力不从心,遂有了集合.

jdk 源码阅读有感(一)String

闲暇之余阅读 jdk 源码. (一)核心属性 /** The value is used for character storage. */ private final char value[]; /** Cache the hash code for the string */ private int hash; // Default to 0 String的核心结构,char型数组与 int 型 hash值. (二)构造器 构造器方面,由于上述两个值是不可更改的,所以直接 对 String

JDK源码阅读环境搭建

内容来源 B站Up主: CodeSheep 视频: https://www.bilibili.com/video/BV1V7411U78L 感谢大佬分享学习心得 Thanks?(?ω?)?~~~ 1. 新建项目 新建JavaSourceLearn项目 新建source包存放源码 新建test包存放测试案例 2. 获取JDK源码 打开Project Structure 选择JDK版本查看安装目录 将src.zip解压到项目source包中 提示: 添加源码到项目之后首次运行需要较长时间进行编译,建

jdk源码阅读-环境配置

我们使用的系统是Ubuntu的系统,代码查看的工具用的是eclipse. 使用以下方法来搭建一个良好的代码阅读环境: 通常在windows下安装好的jdk在其src文件下即可找到对应的jdk类库的源代码.但是在Ubuntu/Linux就不同了.在我查看后发现src文件夹为空. 则可以依照以下方式,下载好openjdk的源代码 http://www.cnblogs.com/super-d2/p/3990354.html 下载好源代码后,我们在windows下可以使用记事本或者ubuntu下的ged

【JDK源码阅读9-util】LinkedHashMap接口

LinkedHashMap接口 一.类继承关系 public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> 二.LinkedHashMap接口特点 与HashMap的异同:同样是基于散列表实现, 区别是LinkedHashMap内部多了一个双向循环链表的维护,该链表是有序,可以按元素插入顺序或元素最近访问顺序(LRU)排列 简单地说:LinkedHashMap=散列表+循环双向链表,能