文档章节

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
博文 98
码字总数 59361
作品 0
浦东
程序员
Java集合----HashSet的实现原理

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

J星星点灯
01/24
0
0
HashTable原理和底层实现

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

道可
01/27
0
0
LinkedHashMap原理和底层实现(未完待续)

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

道可
02/02
0
0
java容器源码分析(四)——HashMap

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

风水书生
2015/12/17
94
0
hashMap实现原理

1、HashMap概述: 1)HashMap实现了Map接口,与HashTable等效,除了HashMap是线程不同步的,且允许空value,空key;且不保证映射的顺序,特别是它不保证顺序恒久不变 2)该实现提供了常量时间...

small达达
2016/02/01
422
0

没有更多内容

加载失败,请刷新页面

加载更多

如何通过 J2Cache 实现分布式 session 存储

做 Java Web 开发的人多数都会需要使用到 session (会话),我们使用 session 来保存一些需要在两个不同的请求之间共享数据。一般 Java 的 Web 容器像 Tomcat、Resin、Jetty 等等,它们会在...

红薯
今天
3
0
C++ std::thread

C++11提供了std::thread类来表示一个多线程对象。 1,首先介绍一下std::this_thread命名空间: (1)std::this_thread::get_id():返回当前线程id (2)std::this_thread::yield():用户接口...

yepanl
今天
3
0
Nignx缓存文件与动态文件自动均衡的配置

下面这段nginx的配置脚本的作用是,自动判断是否存在缓存文件,如果有优先输出缓存文件,不经过php,如果没有,则回到php去处理,同时生成缓存文件。 PHP框架是ThinkPHP,最后一个rewrite有关...

swingcoder
今天
2
0
20180920 usermod命令与用户密码管理

命令 usermod usermod 命令的选项和 useradd 差不多。 一个用户可以属于多个组,但是gid只有一个;除了gid,其他的组(groups)叫做扩展组。 usermod -u 1010 username # 更改用户idusermod ...

野雪球
今天
3
0
Java网络编程基础

1. 简单了解网络通信协议TCP/IP网络模型相关名词 应用层(HTTP,FTP,DNS等) 传输层(TCP,UDP) 网络层(IP,ICMP等) 链路层(驱动程序,接口等) 链路层:用于定义物理传输通道,通常是对...

江左煤郎
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部