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 ...
随机推荐
- 48. Rotate Image (matrix retation, transpose) Amazon problem
You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). ...
- this作用域详解
大家在使用Javascript的时候经常被this这个家伙搞得晕头转向的.在Javascript中它却显得古灵精怪的,因为它不是固定不变的,而是随着它的执行环境的改变而改变.在Javascript中t ...
- 2018.10.31 Mac下的Mysql修改字符编码修改的问题总结
今天在弄数据库的时候发现存入中文汉字变成了问号,Mac跟windows处理方式不一样. show variables like '%char%'; 查看当前mysql的编码格式 也就是默认编码格式 + ...
- maven之构建多模块maven工程
(一)环境搭建 1.Maven下载 ; http://maven.apache.org/download.cgi 第一个在Linux使用,第二个是在Windows,第三和第四是源码: 我们将下 ...
- 实现新layer的时候易犯的错误
实现新layer后,如果我还是在原来的build文件夹里面make,好像是不会编译新的层的,所以跑程序会报没有你新添加的这个层.要么make clear重新make,要么就直接./build.sh,这 ...
- Git命令篇
前文: Git有三种状态,你的文件可能处于其中之一:已提交(committed),已修改(modiffied)和已暂存(staged) 三个工作区域概念:Git仓库.工作目录以及暂存区 Git保存信息 ...
- js获取站点根目录
function getRootPath(){ var strFullPath=window.document.location.href; var strPath=win ...
- html基础用法(上)
html的定义: html超文本标记语言,标准通用标记语言下的一个应用. “超文本”就是指页面内可以包含图片,链接,甚至音乐,程序等非文字语言. 超文本标记语言的结构包括“头”部分(head),和“主 ...
- Object C学习笔记24-关键字总结(转)
学习Object C也有段时间了,学习的过程中涉及到了很多Object C中的关键字,本文总结一下所涉及到的关键字以及基本语法. 1. #import #import <> 从syste ...
- iOS10 开发权限适配设置 崩溃(上传打包后构建版本一直不显示)
ios10 系统必须强制配置系统权限 如果不配置,调试的时候导致崩溃,还会引发包无效的问题,导致上传打包后构建版本一直不显示 解决方案1.在项目中找到info.plist文件,右键点击以 Source ...