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源码注释翻译的更多相关文章

  1. Normalize.css源码注释翻译&浏览器css兼容问题的理解

    版本v5.0.0源码地址: https://necolas.github.io/normalize.css/5.0.0/normalize.css 翻译版: /*! normalize.css v5. ...

  2. HashMap源码学习

    HashMap就是将key做hash算法,然后将hash值映射到内存地址,直接取得key所对应的数据. 关于hash算法的原理知识在之前的博客中有讲到:哈希表之一初步原理了解. 在Java中的Hash ...

  3. 探索HashMap源码 一行一行解析 jdk1.7版本

    今天我们来说一说,HashMap的源码到底是个什么? 面试大厂这方面一定会经常问到,很重要的.以jdk1.7 为标准    先带着大家过一遍 是由数组.链表组成 , 数组的优点是:每个元素有对应下标, ...

  4. HashMap 源码解析

    HashMap简介: HashMap在日常的开发中应用的非常之广泛,它是基于Hash表,实现了Map接口,以键值对(key-value)形式进行数据存储,HashMap在数据结构上使用的是数组+链表. ...

  5. JAVA源码分析-HashMap源码分析(一)

    一直以来,HashMap就是Java面试过程中的常客,不管是刚毕业的,还是工作了好多年的同学,在Java面试过程中,经常会被问到HashMap相关的一些问题,而且每次面试都被问到一些自己平时没有注意的 ...

  6. 【JAVA集合】HashMap源码分析(转载)

    原文出处:http://www.cnblogs.com/chenpi/p/5280304.html 以下内容基于jdk1.7.0_79源码: 什么是HashMap 基于哈希表的一个Map接口实现,存储 ...

  7. 转:【Java集合源码剖析】HashMap源码剖析

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/36034955   您好,我正在参加CSDN博文大赛,如果您喜欢我的文章,希望您能帮我投一票 ...

  8. HashMap 源码详细分析(JDK1.8)

    一.概述 本篇文章我们来聊聊大家日常开发中常用的一个集合类 - HashMap.HashMap 最早出现在 JDK 1.2中,底层基于散列算法实现.HashMap 允许 null 键和 null 值, ...

  9. HashMap源码分析(一)

    前言:相信不管在生产过程中还是面试过程中,HashMap出现的几率都非常的大,因此有必要对其源码进行分析,但要注意的是jdk1.8对HashMap进行了大量的优化,因此笔者会根据不同版本对HashMa ...

随机推荐

  1. Hybris ECP(Enterprise Commerce Platform)的调试

    This blog is written to demonstrate how to setup debug environment for Hybris ECP(Enterprise Commerc ...

  2. python入门19 异常及异常处理 异常捕获

    常见异常举例 """ 一些异常举例:""" '''模块不存在 ModuleNotFoundError: No module named 'd ...

  3. 使flex-direction: column的子元素height: 100%生效的办法

    在flex-direction: column子元素里直接使用height:100%,height并不会被设置成100% <!DOCTYPE html> <html lang=&qu ...

  4. POJ 2771 Guardian of Decency 【最大独立集】

    传送门:http://poj.org/problem?id=2771 Guardian of Decency Time Limit: 3000MS   Memory Limit: 65536K Tot ...

  5. 【JeeSite】区域和菜单管理

    /** * 区域Entity * @author ThinkGem * @version 2013-05-15 */ public class Area extends TreeEntity<A ...

  6. 【luogu P2860 [USACO06JAN]冗余路径Redundant Paths】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2860 考虑在无向图上缩点. 运用到边双.桥的知识. 缩点后统计度为1的点. 度为1是有一条路径,度为2是有两 ...

  7. Android学习笔记_3_四种布局

    Android布局是应用界面开发的重要一环,在Android中,共有四种布局方式, 分别是:FrameLayout( 帧布局 ).LinearLayout (线性布局).TableLayout(表格布 ...

  8. generative models

    A generative model G can be seen as taking a random seed h (say, a sample from a multivariate Normal ...

  9. 论坛数据转换discuz论坛?

    http://www.bbstobbs.com/thread-397-1-1.html

  10. Question 20171114 String的一些问题?

    欢迎各位大神提问题及补充不足和警醒错误! Question 20171113  Java中char为什么占用两个字节? Java是使用Unicode编码的所以Java会将源代码以Unicode的方式编 ...