通过分析JDK源代码研究Hash存储机制

通过 HashMap、HashSet 的源代码分析其 Hash 存储机制

集合和引用

就像引用类型的数组一样,当我们把 Java 对象放入数组之时,并不是真正 的把 Java 对象放入数组中,只是把对象的引用放入数组中,每个数组元素都是 一个引用变量。

实际上,HashSet 和 HashMap 之间有很多相似之处,对于 HashSet 而言, 系统采用 Hash 算法决定集合元素的存储位置,这样可以保证能快速存、取集合 元素;对于 HashMap 而言,系统 key-value 当成一个整体进行处理,系统总是 根据 Hash 算法来计算 key-value 的存储位置,这样可以保证能快速存、取 Map 的 key-value 对。

在介绍集合存储之前需要指出一点:虽然集合号称存储的是 Java 对象,但 实际上并不会真正将 Java 对象放入 Set 集合中,只是在 Set 集合中保留这些 对象的引用而言。也就是说:Java 集合实际上是多个引用变量所组成的集合, 这些引用变量指向实际的 Java 对象。

HashMap 的存储实现

当程序试图将多个 key-value 放入 HashMap 中时,以如下代码片段为例:

HashMap<String , Double> map = new  HashMap<String , Double>();
map.put("语文" , 80.0);
map.put("数学" , 89.0);
map.put("英语" , 78.2);

HashMap 采用一种所谓的“Hash 算法”来决定每个元素的存储位置。

当程序执行 map.put("语文" , 80.0); 时,系统将调用"语文"的 hashCode () 方法得到其 hashCode 值——每个 Java 对象都有 hashCode() 方法,都可 通过该方法获得它的 hashCode 值。得到这个对象的 hashCode 值之后,系统会 根据该 hashCode 值来决定该元素的存储位置。

我们可以看 HashMap 类的 put(K key , V value) 方法的源代码:

public V put(K key, V value)
{
// 如果 key 为 null,调用 putForNullKey 方法进行处理
if (key == null)
return putForNullKey(value);
// 根据 key 的 keyCode 计算 Hash 值
int hash = hash(key.hashCode());
// 搜索指定 hash 值在对应 table 中的索引 
int i = indexFor(hash, table.length);
// 如果 i 索引处的 Entry 不为 null,通过循环不断遍历 e 元 素的下一个元素
for (Entry<K,V> e = table[i]; e != null; e =  e.next)
{
Object k;
// 找到指定 key 与需要放入的 key 相等(hash 值相同
// 通过 equals 比较放回 true)
if (e.hash == hash && ((k = e.key) == key
|| key.equals(k)))
{
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
// 如果 i 索引处的 Entry 为 null,表明此处还没有 Entry
modCount++;
// 将 key、value 添加到 i 索引处
addEntry(hash, key, value, i);
return null;
}

时间: 2024-11-29 00:01:09

通过分析JDK源代码研究Hash存储机制的相关文章

通过分析JDK源代码研究TreeMap红黑树算法实现

简介:TreeMap 和 TreeSet 是 Java Collection Framework 的两个重要成员,其中 TreeMap 是 Map 接口的常用实现类,而 TreeSet 是 Set 接口的常用实现类.虽然 HashMap 和 HashSet 实现的接口规范 不同,但 TreeSet 底层是通过 TreeMap 来实现的,因此二者的实现方式完全一样.而 TreeMap 的实现 就是红黑树算法. TreeMap 的实现就是红黑树数据结构,也就说是一棵自平衡的排序二叉树,这样就可以保证

《深入理解Android 5 源代码》——第2章,第2.2节分析Android源代码结构

2.2 分析Android源代码结构 获得Android 5.0源代码后,源代码的全部工程分为以下3个部分. Core Project:核心工程部分,这是建立Android系统的基础,被保存在根目录的各个文件夹中. External Project:扩展工程部分,可以使其他开源项目具有扩展功能,被保存在"external"文件夹中. Package:包部分,提供了Android的应用程序.内容提供者.输入法和服务,被保存在"package"文件夹中. 在本节的内容中

Kafka文件存储机制及partition和offset

Kafka是什么 Kafka是最初由Linkedin公司开发,是一个分布式.分区的.多副本的.多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx日志.访问日志,消息服务等等,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目. 1.前言 一个商业化消息队列的性能好坏,其文件存储机制设计是衡量一个消息队列服务技术水平和最关键指标之一. 下面将从Kafka文件存储机制和物理结构角度,分析Kafka是如何实现高效文件存储,及

(转载)Kafka文件存储机制那些事

        转自<Kafka文件存储机制那些事>,by美团点评技术团队,地址:http://tech.meituan.com/kafka-fs-design-theory.html         分析的很不错,转载下来!          Kafka是什么 Kafka是最初由Linkedin公司开发,是一个分布式.分区的.多副本的.多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx日志.访问日志,消息服务等等,Linkedin于20

dubbo源码分析系列(1)扩展机制的实现

1 系列目录 dubbo源码分析系列(1)扩展机制的实现 dubbo源码分析系列(2)服务的发布 dubbo源码分析系列(3)服务的引用 dubbo源码分析系列(4)dubbo通信设计 2 SPI扩展机制 站在一个框架作者的角度来说,定义一个接口,自己默认给出几个接口的实现类,同时允许框架的使用者也能够自定义接口的实现.现在一个简单的问题就是:如何优雅的根据一个接口来获取该接口的所有实现类呢? 这就需要引出java的SPI机制了 2.1 SPI介绍与demo 这些内容就不再多说了,网上搜一下,一

NAMENODE工作机制,元数据管理(元数据存储机制、元数据手动查看)、元数据的checkpoint、元数据目录说明(来自学习资料)

NAMENODE工作机制 学习目标:理解namenode的工作机制尤其是元数据管理机制,以增强对HDFS工作原理的理解,及培养hadoop集群运营中"性能调优"."namenode"故障问题的分析解决能力   问题场景: 1.集群启动后,可以查看目录,但是上传文件时报错,打开web页面可看到namenode正处于safemode状态,怎么处理? 解释: safemode是namenode的一种状态(active/standby/safemode安全模式) namen

《Effective Ruby:改善Ruby程序的48条建议》一第10条:推荐使用Struct而非Hash存储结构化数据

第10条:推荐使用Struct而非Hash存储结构化数据 哈希表是Ruby程序员经常使用的一种有用的.通用的数据结构.Hash类提供了使用哈希表的简单的接口,与数组一样,它是Ruby的重要部分之一,该类有自己专用的语法来创建新的实例.当需要使用键值对时,Hash类绝对是首选.事实上,Ruby程序员在任何时候都会使用哈希,甚至方法的参数关键字也是使用Hash类语法糖来实现的.哈希如此通用,因此能被用来对类型进行模拟,比如数组.集合,甚至基本对象.在OOP语言中,当用到结构化数据时,我们往往有比哈希

Kafka文件存储机制那些事

Kafka是什么 Kafka是最初由Linkedin公司开发,是一个分布式.分区的.多副本的.多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx日志.访问日志,消息服务等等,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目. 1.前言 一个商业化消息队列的性能好坏,其文件存储机制设计是衡量一个消息队列服务技术水平和最关键指标之一. 下面将从Kafka文件存储机制和物理结构角度,分析Kafka是如何实现高效文件存储,及

基于分割的数字图像云存储机制

基于分割的数字图像云存储机制 吕骁博 郭耀 陈向群 随着云计算和数据中心的发展,数据处理和存储工作逐渐转移到云平台上. 通过云服务器存储数字图像可以解决图像存储和共享的问题,但是一些云服务器可能难以保证这些数字图像数据的可靠性和可用性,导致用户隐私泄露. 本文提出了一种基于分割的数字图像云存储机制,并采用了两种不同的图像分割算法:分块分割和分层分割.为了验证该机制,实现了一个支持隐私保护的数字图像云存储工具,针对不同图像分割方法进行了比较分析与实现,对所选的不同云服务器服务质量进行了测试. 通过