文档章节

HashMap实现原理概述

6pker
 6pker
发布于 2016/02/03 11:40
字数 823
阅读 132
收藏 17

1. HashMap的数据结构

数据结构中有数组链表来实现对数据的存储,但这两者基本上是两个极端。


数组

数组存储区间是连续的,占用内存严重,故空间复杂的很大。

但数组的二分查找时间复杂度小,为O(1);

数组的特点是:寻址容易,插入和删除困难


链表

链表存储区间离散,占用内存比较宽松,故空间复杂度很小。

但时间复杂度很大,达O(N)。

链表的特点是寻址困难,插入和删除容易。


哈希表

哈希表((Hash table)既满足了数据的查找方便,同时不占用太多的内容空间,使用也十分方便。

哈希表有多种不同的实现方法,我接下来解释的是最常用的一种方法—— 拉链法,我们可以理解为“链表的数组” ,如图:



从上图我们可以发现哈希表是由数组+链表组成的,一个长度为16的数组中,每个元素存储的是一个链表的头结点。

那么这 些元素是按照什么样的规则存储到数组中呢。

一般情况是通过hash(key)%len获得,也就是元素的key的哈希值对数组长度取模得到。

比如上述哈希 表中,12%16=12,28%16=12,108%16=12,140%16=12。所以12、28、108以及140都存储在数组下标为12的位置。


HashMap其实也是一个线性的数组实现的,所以可以理解为其存储数据的容器就是一个线性数组。

首先HashMap里面实现一个静态内部类Entry,其重要的属性有key , value, next

从属性key,value我们就能很明显的看出来Entry就是HashMap键值对实现的一个基础bean,我们上面说到HashMap的基础就是一个线性数组,这个数组就是Entry[],Map里面的内容都保存在Entry[]里面。


2. HashMap的存取实现

  既然是线性数组,为什么能随机存取?这里HashMap用了一个小算法,大致是这样实现:

// 存储时:
int hash = key.hashCode(); // 这个hashCode方法这里不详述,只要理解每个key的hash是一个固定的int值
int index = hash % Entry[].length;
Entry[index] = value;

// 取值时:
int hash = key.hashCode();
int index = hash % Entry[].length;
return Entry[index];


这里HashMap里面用到链式数据结构的一个概念。

上面我们提到过Entry类里面有一个next属性,作用是指向下一个Entry。

打个比方, 第一个键值对A进来,通过计算其key的hash得到的index=0,记做: Entry[0] = A

一会后又进来一个键值对B,通过计算其index也等于0,现在怎么办?

HashMap会这样做: B.next = A, Entry[0] = B,

如果又进来C, index也等于0, 那么 C.next = B, Entry[0] = C

这样我们发现index=0的地方其实存取了A,B,C三个键值对, 他们通过next这个属性链接在一起。

所以疑问不用担心。也就是说数组中存储的是最后插入的元素到这里为止,HashMap的大致实现,我们应该已经清楚了。



本文转载自:http://blog.csdn.net/vking_wang/article/details/14166593

共有 人打赏支持
6pker
粉丝 51
博文 97
码字总数 59252
作品 0
浦东
程序员
私信 提问
Java集合----HashSet的实现原理

1. HashSet概述: HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持。它不保证set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用null元素。 2. HashSet的实现: 对于...

J星星点灯
01/24
0
0
java容器源码分析(四)——HashMap

本文内容: Hash HashMap概述 HashMap源码分析 Hash表 数据结构中都学过Hash,我们要说的HashMap采用拉链法(数组+链表)实现。数组具有根据下标快速查找的特点,链表动态增加删除元素。 (来...

风水书生
2015/12/17
94
0
LinkedHashMap原理和底层实现(未完待续)

1.概述 在使用HashMap的时候,可能会遇到需要按照当时put的顺序来进行哈希表的遍历。通过上篇对HashMap的了解,我们知道HashMap中不存在保存顺序的机制。本篇文章要介绍的LinkedHashMap专为此...

道可
02/02
0
0
HashTable原理和底层实现

1. 概述 上次讨论了HashMap的结构,原理和实现,本文来对Map家族的另外一个常用集合HashTable进行介绍。HashTable和HashMap两种集合非常相似,经常被各种面试官问到两者的区别。 对于两者的区...

道可
01/27
0
0
Java集合 --- HashSet底层实现和原理(源码解析)

概述 文章的内容基于JDK1.7进行分析,之所以选用这个版本,是因为1.8的有些类做了改动,增加了阅读的难度,虽然是1.7,但是对于1.8做了重大改动的内容,文章也会进行说明。 HashSet是Set接口...

起个名忒难
2017/08/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

JSON数据从OSS迁移到MaxCompute最佳实践

摘要: 本文为您介绍如何利用DataWorks数据集成将JSON数据从OSS迁移到MaxCompute,并使用MaxCompute内置字符串函数GET_JSON_OBJECT提取JSON信息。 本文为您介绍如何利用DataWorks数据集成将J...

阿里云官方博客
23分钟前
3
0
LockSupport 源码

LockSupport 主要利用了Unsafe类中提供的part和unpart两个方法.而LockSupport类暴露出来的两个核心接口也是part和unpart两个. java.util.concurrent.locks.LockSupport源码: package java...

狼王黄师傅
24分钟前
2
0
《阿里巴巴 Java开发手册》读后感

前言 只有光头才能变强 前一阵子一直在学Redis,结果在黄金段位被虐了,暂时升不了段位了,每天都拿不到首胜(好烦)。 趁着学校校运会,合理地给自己放了一个小长假,然后就回家了。回到家才发...

Java3y
25分钟前
0
0
Mac sorceTree一直显示Passwprd Required

sourceTree 1.我是从码云上建了一个项目然后下载下来再推上去的是就报这个错 解决方法 打开sourceTree偏好设置===》打开网络===》修改url路径(这个就是你登录码云的用户名)...

潇潇程序缘
26分钟前
1
0
如何创建和部署一个属于自己的EOS代币

本文我们将弄清楚什么是EOS代币以及如何自己创建和部署EOS代币。 与以太坊相反,EOS带有即插即用的代币智能合约。以太坊拥有ERC20智能合约,EOS拥有eosio.token智能合约。Eosio.token智能合约...

笔阁
26分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部