`
拓子轩
  • 浏览: 210700 次
  • 性别: 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的实现原理之前,我们需要了解两个关键的接口方法:`hashCode()`和`equals()`。 根据《Effective JAVA》的建议,当重写`equals()`方法时,也应重写`hashCode()`方法。这是因为在HashMap中,`...

    HashMap源码分析

    HashMap 的核心原理是将键(key)通过哈希函数转化为数组索引,然后将键值对(key-value pair)存储在数组的对应位置。如果多个键经过哈希计算得到相同的索引,HashMap 利用链表处理这种哈希冲突,形成链式存储。 ...

    面试必考之HashMap源码分析与实现

    面试中,HashMap的源码分析与实现是一个常见的考察点,因为它涉及到数据结构、并发处理和性能优化等多个核心领域。本篇文章将深入探讨HashMap的内部工作原理、关键特性以及其在实际应用中的考量因素。 HashMap基于...

    HashMap的实现原理

    ### HashMap的实现原理 #### 1. HashMap概述 HashMap 是 Java 集合框架中一个非常重要的类,它实现了 Map 接口,并提供了基于哈希表的存储方式。与其它 Map 实现不同的是,HashMap 允许使用 `null` 键和 `null` 值...

    HashMap 源码分析

    《HashMap 源码解析——JDK11版本》 HashMap是Java中广泛使用的非同步散列表,其设计和实现是高效且灵活的。在JDK1.8之前,HashMap的底层数据结构采用的是数组+链表的方式,这种方式称为“拉链法”来解决哈希冲突。...

    电话本管理系统HashMap实现

    本文将深入探讨如何使用HashMap来构建一个电话本管理系统,并通过源码分析增强理解。 HashMap是Java集合框架中的一个核心类,它实现了Map接口。Map接口存储键值对(key-value pairs),而HashMap则使用哈希表数据...

    HashMap与HashTable的区别(含源码分析)

    5. 源码分析: 查看`HashTable`和`HashMap`的源码,可以发现两者在内部实现上也有所不同。`HashTable`直接使用了数组+链表的方式,而`HashMap`在Java 8及以后版本引入了红黑树优化,当链表长度达到一定阈值(8)时...

    HashMap put方法的源码分析

    本文将深入解析Java 1.8中HashMap的put方法源码,探讨其内部工作原理。 首先,我们了解HashMap的基本结构。在Java 1.8中,HashMap由数组加链表或红黑树构成。初始容量为16,这是通过`DEFAULT_INITIAL_CAPACITY`常量...

    易语言源码易语言HashMap类源码.rar

    通过分析和学习易语言HashMap类的源码,开发者可以深入理解哈希表的工作原理,以及易语言如何实现高效的数据结构。这对于提升编程技能,尤其是理解和优化数据结构的性能,具有很大的帮助。同时,源码也可以作为参考...

    学习笔记:三数组实现的HashMap

    "学习笔记:三数组实现的HashMap"这篇博客文章可能讨论了一种非标准但有趣的HashMap实现,使用了三个数组来代替标准的哈希表结构。这里我们将深入探讨这种三数组实现HashMap的原理和可能的优势。 1. **基本概念**:...

    HashMap类

    HashMap类在Java编程...在阅读《HashMap1.js》和《HashMap.js》这两个文件时,可以深入分析其JavaScript版本的HashMap实现,虽然与Java版本可能有所不同,但基本的哈希映射原理是相通的,有助于拓宽对哈希表的理解。

    HashMap源码分析系列-第四弹:HashMap多线程解决方案.docx

    #### 二、HashMap线程安全问题分析 在多线程环境中,`HashMap`的主要线程安全问题包括但不限于: 1. **链表死循环问题**:在JDK 1.7中,当多个线程同时进行`put`操作时,可能会出现链表死循环的情况,这是一个严重...

    Java集合系列之HashMap源码分析

    Java集合系列之HashMap源码分析 Java集合系列之HashMap源码分析是Java集合系列中的一篇非常重要的...HashMap源码分析是非常重要的,它能够帮助我们更好地理解HashMap的内部机制和实现原理,从而更好地使用HashMap。

    手写HashMap源码.rar

    在面试过程中,尤其是2020年及以后的技术面试中,深入理解HashMap的实现原理成为了考察候选人基础技能的重要环节。本篇文章将通过分析一个名为"MyHashMap"的手写HashMap源码,来探讨HashMap的内部机制,帮助提升编程...

    Android+上百实例源码分析以及开源分析+集合打包3

    这些数据结构在Android应用中广泛使用,理解它们的底层实现原理和性能特性,能够帮助开发者选择最适合的数据结构来存储和处理数据,从而提高程序的运行效率。 开源分析部分则强调了社区力量在Android开发中的作用。...

    HashMap类.rar

    通过分析源码,开发者可以深入理解哈希表的工作原理,学习如何在易语言中实现高效的数据结构,这对于提升程序性能和优化内存管理至关重要。同时,这也为自定义数据结构或实现其他哈希表相关的功能提供了基础。

Global site tag (gtag.js) - Google Analytics