`
拓子轩
  • 浏览: 204467 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

HashMap的实现原理及源码分析

    博客分类:
  • java
阅读更多

一、HashMap概述

    HashMap通过键值的方式存储数据,为非线程安全的类,键和值可以为null,键不能重复,继承了AbstractMap并实现了Map接口

 

二、源码分析(基于JDK1.7)

 

1. HashMap中的主要成员变量

 

DEFAULT_INITIAL_CAPACITY:静态整型常量,默认初始化的容量,其值为16(必须是2的指数倍)

MAXIMUM_CAPACITY:静态整型常量,表示最大容量为2的30次方。如果通过构造器传入的容量大于最大容量,会被此最大容量值替换

DEFAULT_LOAD_FACTOR:静态浮点型常量,表示默认的加载因子,其值为0.75f;如果在构造器中没有指定加载因子,则使用此默认值

table:存储数据的Entry数组(Entry<K,V>[]),会做必要的调整,长度是2的指数倍

size:HashMap的大小,是保存在HashMap里key-value键值对的数量

threshold:HashMap的阈值,用于判断是否要调整HashMap的容量,其值等于容量*加载因子

loadFactor:加载因子实际大小,常量

modCount:HashMap被改变的次数

 

2. HashMap中的读取(get方法)

2.1 如果传入的键(key)为null,则从Entry数组table中索引下标为0的链表中查找key为null的值并返回,未找到则返回null

2.2 如果传入的键(key)不为null,则获取key对应的哈希值hash

2.3 通过哈希值hash获取对应在table数组中的索引下标(h & (length-1))

2.4 循环遍历table数组中该索引下标对应的Entry链表

2.5 如果传入的键(key)的哈希值(hash)等于该Entry的哈希值(hash),

     并且传入的键(key)等于(==)或等同于(equals)该Entry的key,

     则此Entry便是要查找的Entry对象,遍历完该Entry链表如果还未查找到,则返回null

2.6 返回查找到的Entry对象的值(value),未查找到则返回null

 

3. HashMap中存入键值(put方法)

3.1 如果key为null,则从Entry数组table中索引下标为0的链表中,

     查找是否已经存在了key为null的Entry,如果存在则替换这个Entry的值为新的值,并返回旧值;

     如果不存在key为null的Entry,则先把修改数(modCount)自增1,然后添加一个新的Entry,

     key为null,value为传入的值,并把该Entry放入table[0]位置上链表的头部,并返回null。

3.2 如果key不为null,先获取key的哈希值hash,并通过hash确定Entry数组table的索引下标i

     对table[i]位置的链表进行循环遍历,查找是否已经存在key值相同的Entry(传入key的哈希值

     与该Entry的哈希值相等,并且传入key等于或等同于Entry的key),如果存在则把它的值替换

     成新值,并返回旧值;

     如果不存在,则先把修改数(modCount)自增1,然后在table[i]对应的链表的头部添加一个Entry

     并返回null。

 

三、要点分析

 

1. 链表的原理和实现

    HashMap中的链表由Entry类组成,Entry包含三个元素:key,value和next(指向下一个Entry的)

    在HashMap中的链表加入新的Entry,会放在链表头部位置,新的Entry的next元素指向原来在链表头部的Entry

 

2. modCount的作用

    modCount为修改次数,在进行put、remove、clear等操作时会修改数modCount加1

    HashMap中不是线程安全的,如果在使用迭代器的过程中有其他线程修改了HashMap,那么将抛出ConcurrentModificationException,即Fail-Fast策略

    在迭代过程中,是通过modCount跟expectedModCount是否相等来判定其他线程有没有修改的,如果不相等,说明其他线程修改了

 

四、总结

 

1. HashMap是基于哈希表的Map接口的非同步实现,允许key和vaue为null

2. HashMap内部是有数组和链表实现的,通过key的哈希值找到在数组中位置,

    并遍历该位置的链表,找到key值相同的Entry。

3. 当我们往hashmap中put元素的时候,先根据key的hash值得到这个元素在数组中的位置(即下标),

    然后就可以把这个元素放到对应的位置中了。如果这个元素所在的位子上已经存放有其他元素了,

    那么在同一个位子上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。

    从hashmap中get元素时,首先计算key的hashcode,找到数组中对应位置的某一元素,

    然后通过key的equals方法在对应位置的链表中找到需要的元素。从这里我们可以想象得到,

    如果每个位置上的链表只有一个元素,那么hashmap的get效率将是最高的

 

0
1
分享到:
评论

相关推荐

    hashmap实现原理

    hashmap的底层及源码解析,很适合大家的学习,不要积分。

    HashMap 源码分析

    首先,我们了解一下HashMap的底层结构历史,在JDK1.8之前采用的是数组+链表的数据结构来存储数据,是不是觉得很熟悉,没错这玩意在1.8之前的结构就和HashTable一样都是采用数组+链表,同样也是通过链地址法(这里简称...

    在Java8与Java7中HashMap源码实现的对比

    主要介绍了在Java8与Java7中HashMap源码实现的对比,内容包括HashMap 的原理简单介绍、结合源码在Java7中是如何解决hash冲突的以及优缺点,结合源码以及在Java8中如何解决hash冲突,balance tree相关源码介绍,需要的...

    HashMap集合,最详细底层源码分析及put ,get方法运行原理

    HashMap集合继承关系,实现的接口有: public class HashMap extends AbstractMap implements Map, Cloneable, Serializable { } HashMap集合继承了Map集合,实现了Map,Cloneable,Serializable接口 从继承Map...

    Java开发面试必备知识技能总结视频合集

    HashMap源码分析与实现、JVM底层奥秘ClassLoader源码分析与案例讲解、大型网站数据库瓶颈之数据库分库分表方案实践、Spring Cloud Eureka场景分析与实战、分库分表之后分布式下如何保证ID全局唯一性、RPC底层通讯...

    java8集合源码分析-Outline:大纲

    集合源码分析 JAVA: 基本语法 static 修饰变量 方法 静态块(初始化块 构造函数 ) 静态内部类() 静态导包 final() transient() foreach循环原理() volatile底层实现() equals和hashcode(, ) string,stringbuffer和...

    spring-annotation:1.Spring 5.X源码分析2.手写框架3.设计模式4.Springcloud2 5.互联网高并发场景6.互联网安全架构

    Conditional,@ Import注解1.1.3 Spring5深度源码分析(三)之AnnotationConfigApplicationContext启动原理分析2.手写框架2.1手写Spring事务框架2.2手写@服务和@资源注解2.3手写SpringMVC框架(手写SpringMVC控制框...

    最新Java面试题视频网盘,Java面试题84集、java面试专属及面试必问课程

    面试必考之HashMap源码分析与实现.mp4 │ │ │ ├─2.探索JVM底层奥秘ClassLoader源码分析与案例讲解 │ │ 2.探索JVM底层奥秘ClassLoader源码分析与案例讲解.wmv │ │ │ ├─3.锁、分布式锁、无锁实战全局性ID...

    java8stream源码-doc:一步一步建立起分布式系统:SOA->微服务->云原生的一套完整技术栈

    HashMap源码分析 并发 IO JVM 类加载机制与编译优化 JVM运行时数据区的内存管理机制 垃圾收集算法与垃圾收集器 性能监控与故障处理 常用设计模式 ​ 用好设计模式能帮助我们更好的解决实际问题,设计模式最重要的是...

    java8源码-cainiao:自娱自乐

    说明:文件夹以类型为目录,如并发、JVM、设计模式,文件名称尽量描述主题,如HASHMAP源码分析、代理模式分析 Books中存放分布式技术学习和书籍阅读后笔记、总结和一些面试搜集的问题,具体查看Books中ReadMe.md ...

    免费下载:C语言难点分析整理.doc

    50. 游戏外挂的编写原理 254 51. 程序实例分析-为什么会陷入死循环 258 52. 空指针究竟指向了内存的哪个地方 260 53. 算术表达式的计算 265 54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法...

    大型国企内部Java面试题

    主要是Java后端的,16K左右的,涉及SE、WEB、三大框架SSM、springboot、MQ、数据库、springcloud、JVM、Redis、多线程、hashmap的底层、面试技巧等 SSM涉及浅层的底层,如IOC、AOP,专为没看过源码的人应付面试准备...

    C语言难点分析整理.doc

    1. C 语言中的指针和内存...80. Hashtable和HashMap的区别 408 81. hash 表学习笔记 410 82. C程序设计常用算法源代码 412 83. C语言有头结点链表的经典实现 419 84. C语言惠通面试题 428 85. C语言常用宏定义 450

    java面试常见基础(深层次,高级研发)

    CyclicBarrier源码分析(基于JDK1.7.0_40) 52 23.3.1. 3.1 构造函数 52 23.3.2. 3.2 等待函数 53 23.4. 4. CyclicBarrier的使用示例 57 23.4.1. 示例1 57 23.4.2. 示例2 59 24. Blockingqueue有几种形式?各自的编码...

    c语言难点分析整理,C语言

    50. 游戏外挂的编写原理 254 51. 程序实例分析-为什么会陷入死循环 258 52. 空指针究竟指向了内存的哪个地方 260 53. 算术表达式的计算 265 54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法...

    java基础案例与开发详解案例源码全

    11.4.1 实现类HashMap284 11.4.2 实现类LinkedHashMap285 11.4.3 实现类TreeMap286 11.4.4 实现类Properties287 11.5 Collections类288 11.6 泛型概述292 11.7 本章习题300 第12章 12.1 理解线程304 12.1.1 什么是多...

    C语言难点分析整理

    50. 游戏外挂的编写原理 254 51. 程序实例分析-为什么会陷入死循环 258 52. 空指针究竟指向了内存的哪个地方 260 53. 算术表达式的计算 265 54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法...

    百度地图毕业设计源码-interview-guide:面试指南

    百度地图毕业设计源码 面试内容的汇总 目录 其他人的汇总 面试经历 面试题 Java JVM IO/NIO 锁 ThreadLocal ...源码 ...如何设计一个可达性分析系统 ...偏向锁/轻量级锁/重量级锁的原理 ...redis和zookeeper如何实现分布式锁

    高级C语言 C 语言编程要点

    50. 游戏外挂的编写原理 254 51. 程序实例分析-为什么会陷入死循环 258 52. 空指针究竟指向了内存的哪个地方 260 53. 算术表达式的计算 265 54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法...

    高级进阶c语言教程..doc

    50. 游戏外挂的编写原理 254 51. 程序实例分析-为什么会陷入死循环 258 52. 空指针究竟指向了内存的哪个地方 260 53. 算术表达式的计算 265 54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法...

Global site tag (gtag.js) - Google Analytics