HashMap源码注释翻译
HashMap.java(JDK1.8)
如有错误翻译的地方,欢迎评论指出。
介绍:对于HashMap及其子类而言,它们采用Hash算法来决定集合中元素的存储位置。当系统开始初始化HashMap时,系统会创建一个长度为capacity的Entry数组,这个数组里可以存储元素的位置被称为“桶(bucket)”,每个bucket都有其指定索引,系统可以根据其索引快速访问该bucket里存储的元素。需要明确的是,HashMap是一个以空间换取时间的数据结构。
JDK注释
/**
Hash table实现了Map接口。这个实现提供了对Map所有的可选择操作,同时允许null的Key和Value(除了unsynchronized的和允许nulls,HashMap和Hashtable是大致一致的)。Hashtable这个类不保证对Map进行排序;同时不保证数据在Map里面的顺序保持不变。
假设hash方法把元素合理的散布在buckets里面,那么HashMap这个实现的基本操作get和put可以保持一个恒定的时间性能。collection视图的迭代时间与HashMap实例的容量(buckets的数量)加它的大小(键值映射的数量)成正比。因此,如果迭代的性能比较重要,那么设置一个不是十分高的初始容量(或很低的负载因子)是很重要的。
一个HashMap实例有两个参数会影响其性能:初始容量和负载因子。容量是指hash table中的bucket数量,初始容量就是指hash table在被创建时的容量。负载因子是在容量自动增长之前对hash table充满程度的一种度量。当hash table里面的条目数超过了负载因子和当前容量的乘积时,hash table将被rehash(内部数据结构重建),这样子hash table就会有大约两倍于现在的bucket数量。
一般来说,默认的负载因子(0.75)在时间花费和空间占用上提供了一个比较好的权衡。更高的数值可以降低空间开销但是增加查询开销(反应在HashMap类的大部分操作上,比如get和put)。Map中预期数据条目数和负载因子应该在设置初始容量时被考虑到,以便减少rehash操作次数。如果初始容量大于最大条目数除以负载因子,那么rehash操作将不会发生。
当有许多键值映射要被存储到HashMap实例中,相比于让它按需自动rehash来增长空间,用一个足够大的容量来创建实例存储键值映射更加高效。需要注意的是,任何hash table当使用许多具有相同hashcode的key,都是一个明确会降低性能的方式。为了改善影响,当keys是可比较的,这个类可以在keys之间使用比较来排序帮助断开关联。
需要注意的是,这个实现不是同步的。如果有多个线程同时访问hash map,并且至少有一个线程对map进行了结构性修改,这在外部必须用synchronized进行修饰(结构性修改指的是对一个或多个键值映射进行增删的操作;仅仅只是修改实例现有key的value并不属于结构新修改)。这通常是通过对自然封装map的那个对象进行同步来实现的。
如果没有这样的对象存在,那么map应该用Collections.synchronizedMap()方法来包裹。这最好在创建的时候,已避免意外的对map的非同步访问。
Map m = Collections.synchronizedMap(new HashMap(…));
这个类由“集合视图方法”返回的迭代器都是“fail-fast”的:如果map在迭代器被创建后的任何时间点里被结构性修改了,除了迭代器自己的remove方法,其它任何方法都会引起迭代器抛出ConcurrentModificationException的异常。因此,当面临同时的修改时,迭代器将干净的迅速的fails,而不是冒着在将来的不确定时间点出现的任意的不确定的形式的风险。
需要注意的是,迭代器的fail-fast表现不能保证和其定义的一样,一般来说,在存在不同步的同时修改情况下是不可能做出明确的保证的。Fail-fast迭代器在尽最大努力的基础上抛出ConcurrentModificationException异常。因为,编程时依赖捕获这个异常来确保正确性是错误的做法:迭代器的fail-fast特性只应该被用于检测bugs。
**/
JDK参数
/**
默认初始容量 – 必须是2的次方
**/
DEFAULT_INITIAL_CAPACITY = 1 << 4 (16)
/**
最大容量,如果一个更高的值被构造函数用参数隐式指定,那么依旧使用和这个容量
必须是2的次方
**/
MAXIMUM_CAPACITY = 1 << 30 (2的30次方)
/**
当没有在构造函数里面指定,将使用这个默认负载因子
**/
DEFAULT_LOAD_FACTOR = 0.75
/**
一个bucket的树化阈值(红黑树)
为bin使用tree还是list一个bin数目阈值。在至少达到这个数目节点的情况下增加元素,bins将会转化成tree。该值必须大于2,至少应该是8,与移除树的假设相适应。
**/
TREEIFY_THERSHOLD = 8
/**
一个树的链表还原阈值
在调整大小操作时反树化(切分)一个bin的bin数目阈值,在移除时检测最大是6。
**/
UNTREEIFY_THRESHOLD = 6
/**
树形化时bins的最小哈希表容量(否则如果bin中有太多的节点就对哈希表调整大小)。为避免在调整大小和树形化阈值之间产生矛盾,这个值至少是4 * TREEIFY_THERSHOLD。
(假如在一个bin上出现了一个长度>=TREEIFY_THERSHOLD-1的链表,那么判断整个hashMap的节点数量是否大于MIN_TREEIFY_CAPACITY,如果没有则进行resize,如果大于了,针对bin上的链表进行“树化”)
**/
MIN_TREEIFY_CAPACITY = 64
/**
table,在第一次使用时被初始化,必要时会调整大小。被分配后,其长度一直是2的次方(在当前不需要的引导机制下,我们也容许在一些操作中其长度为0)。
**/
Node<K,V>[] table
/**
拥有缓存的entrySet()。需要注意的是,AbstractMap域里面使用的是keySet()和values()。
**/
Set<Map.Entry<K,V>> entrySet
/**
这个map里面包含的键值对的个数
**/
int size
/**
这个HashMap被结构性修改的次数。结构性修改是那些改变了HashMap里面键值对个数或其它它的内部结构修改(例如rehash)。这个域是用于迭代器在集合视图中的fail-fast。
**/
int modCount
/**
需要进行调整大小时的阈值(capacity*load factor)
**/
int threshold
/**
Hash table的负载因子
**/
float loadFactor
HashMap源码注释翻译的更多相关文章
- Normalize.css源码注释翻译&浏览器css兼容问题的理解
版本v5.0.0源码地址: https://necolas.github.io/normalize.css/5.0.0/normalize.css 翻译版: /*! normalize.css v5. ...
- HashMap源码学习
HashMap就是将key做hash算法,然后将hash值映射到内存地址,直接取得key所对应的数据. 关于hash算法的原理知识在之前的博客中有讲到:哈希表之一初步原理了解. 在Java中的Hash ...
- 探索HashMap源码 一行一行解析 jdk1.7版本
今天我们来说一说,HashMap的源码到底是个什么? 面试大厂这方面一定会经常问到,很重要的.以jdk1.7 为标准 先带着大家过一遍 是由数组.链表组成 , 数组的优点是:每个元素有对应下标, ...
- HashMap 源码解析
HashMap简介: HashMap在日常的开发中应用的非常之广泛,它是基于Hash表,实现了Map接口,以键值对(key-value)形式进行数据存储,HashMap在数据结构上使用的是数组+链表. ...
- JAVA源码分析-HashMap源码分析(一)
一直以来,HashMap就是Java面试过程中的常客,不管是刚毕业的,还是工作了好多年的同学,在Java面试过程中,经常会被问到HashMap相关的一些问题,而且每次面试都被问到一些自己平时没有注意的 ...
- 【JAVA集合】HashMap源码分析(转载)
原文出处:http://www.cnblogs.com/chenpi/p/5280304.html 以下内容基于jdk1.7.0_79源码: 什么是HashMap 基于哈希表的一个Map接口实现,存储 ...
- 转:【Java集合源码剖析】HashMap源码剖析
转载请注明出处:http://blog.csdn.net/ns_code/article/details/36034955 您好,我正在参加CSDN博文大赛,如果您喜欢我的文章,希望您能帮我投一票 ...
- HashMap 源码详细分析(JDK1.8)
一.概述 本篇文章我们来聊聊大家日常开发中常用的一个集合类 - HashMap.HashMap 最早出现在 JDK 1.2中,底层基于散列算法实现.HashMap 允许 null 键和 null 值, ...
- HashMap源码分析(一)
前言:相信不管在生产过程中还是面试过程中,HashMap出现的几率都非常的大,因此有必要对其源码进行分析,但要注意的是jdk1.8对HashMap进行了大量的优化,因此笔者会根据不同版本对HashMa ...
随机推荐
- C++11新特性之 std::forward(完美转发)
我们也要时刻清醒,有时候右值会转为左值,左值会转为右值. (也许“转换”二字用的不是很准确) 如果我们要避免这种转换呢? 我们需要一种方法能按照参数原来的类型转发到另一个函数中,这才完美,我们称之为完 ...
- linux下vi的一些简单的操作
前言 在嵌入式linux开发中,进行需要修改一下配置文件之类的,必须使用vi,因此,熟悉 vi 的一些基本操作,有助于提高工作效率. 一,模式 vi编辑器有3种模式:命令模式.输入模式.末行模式.掌握 ...
- pthread的各种同步机制
https://casatwy.com/pthreadde-ge-chong-tong-bu-ji-zhi.html pthread是POSIX标准的多线程库,UNIX.Linux上广泛使用,wind ...
- 效率对比:各种语言构造100W个时间对象
原本是用perl写了一个通过给定的时间范围来筛选一个比较大的日志文件.但是测试发现筛选130W行日志需要2分多钟,对其中几个低效率函数单独进行了效率测试,发现构造100W个时间对象所花时间也是个大户. ...
- Maximum Profit
Maximum Profit You can obtain profits from foreign exchange margin transactions. For example, if you ...
- ASP.NET SignalR 与LayIM配合,轻松实现网站客服聊天室(七)之 图文,附件消息(2016-05-05 12:13)
上一篇介绍了加好友的流程,这里不再赘述,不过之前的聊天只能发送普通文字,那么本篇就教你如何实现发送附件和图片消息.我们先对功能进行分析: 发送图片,附件,需要实现上传图片和附件的功能. textare ...
- 【Openjudge 9277 Logs Stacking堆木头】 题解
题目链接:http://noi.openjudge.cn/ch0206/9277/ ... #include <algorithm> #include <iostream> # ...
- EJB结合struts2创建项目、发布jboss服务器和访问、父类(BaseDaoImpl)的封装
一.环境搭建: 1.准备jboss服务器,将对应数据库的xml配置好放到jboss的发布目录下. <?xml version="1.0" encoding="UTF ...
- python序列化_json,pickle,shelve模块
序列化 序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes 把内存数据 转成字符,叫序列化 把字符 转成内存数据,叫反序列化 模块 ...
- C#结构体和字节数组的转换函数
在通信过程中,一般我们都会操作到字节数组.特别是希望在不同语言编程进行操作的时候. 虽然C#提供了序列化的支持,不用字节数组也行.但操作字节数组肯定会碰到. 一般都会采用结构来表示字节数组.但结构 ...