【多图预警,不懂来敲我】图说HashMap原理和流程

1.前言

HashMap是开发中最常用的键值对集合类,也是面试中经常被问及的一个知识点,也是衡量java基础是否扎实的标准之一,是每个JAVA初学者入门必须跨过的槛。所以HashMap重要性不言而喻,需要彻底掌握。 但在开始学习HashMap时,如果文章中有一大堆源码和一大段文字,会让读者阅读起来十分枯燥以及苦涩难懂。特别是不太了解HashMap的读者,但为了深入理解肯定要结合源码学习。 所以打算先介绍HashMap流程,熟悉主要操作的流程步骤,再结合源码,加深对HashMap的理解。分为两篇文章讲解:
第一篇(本文)是介绍HashMap主要操作的流程。
第二篇是结合源码深入理解。
本文为第一篇文章,尽量以简短的文字+图片讲解HashMap,力求达到通俗易懂,也会叠加一小部分代码,方便第二篇文章源码阅读。

2.原理

HashMap底层基于拉链式的哈希算法实现。底层数据结构是数组+链表+红黑树组成。数据结构示意图如下:

简单的数组+链表图

当进行增删查操作时,首先确定元素在桶数组的位置,再遍历数组中的链表或红黑树定位元素。举个实例说明查找元素的过程,假设桶的数组长度为16,我们需要确认元素37是否在HashMap中,步骤如下:

  1. 定位元素37所在的桶数组位置,index = 37 % 16 = 5
  2. 遍历5号桶里的链表,发现37在链表中

以上就是HashMap定位元素的流程。集合中不管是增(put)、删(remove)、查(get)操作,第一步需要先定位元素的位置。接下来先详细分析这两个步骤具体实现。

3.定位元素

3.1确定桶数组的位置

3.1.1对数组长度取余

定位元素第一步要确定在桶数组中具体的位置。为了确保元素落在桶数组范围内,所以用元素对数组长度取余来确定位置。比如上面提到的例子,元素的hash值37在长度为16的桶数组中,37 % 16 = 5,最终会在数组索引值为5的桶中。

在这里插入图片描述

3.1.2优化:&运算替换%

在HashMap实际代码(如下所示)中,hash值并不是与桶数组长度进行取余运算,而是用&运算。

//index桶数组索引,tab为桶数组名,n为桶数组长度
index = tab[(n - 1) & hash]

这里你肯定会问,为什么%要换成&运算呢?其实是因为&运算,是位运算,而%取余不是位运算,系统底层用的是位运算,对于%取余操作需要转换后才能运算,所以**&运算比取余操作效率高**。

你也肯定会问,为什么&能替代%操作?是因为HashMap中桶数组长度length总是2的次幂,此时 (length - 1) & hash 等价于对length取余。举个例子说明下,假如hash值为37,数组长度length为16,计算过程如下图所示。

在这里插入图片描述

3.1.3hash算法

在确定桶数组位置的过程,你或许会问hash值是元素的hashcode的值吗?答案:不是。实际代码(如下所示)中&#

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值