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. Ubuntu环境安装Gradle

    AndroidStudio使用全新的构建系列—–Gradle. 这是官方为什么使用gradle 的理由: Domain Specific Language (DSL) to describe and ...

  2. bzoj5000 OI树

    Description 几天之后小跳蚤即将结束自己在lydsy星球上的旅行.这时,lydsy人却发现他们的超空间传送装置的能量早在小跳蚤通过石板来到lydsy星球时就已经消耗光了.这时,小跳蚤了解到自 ...

  3. Softmax实现 fashion.mnist 分类

    softmax #!/usr/bin/env python # coding: utf-8 # In[1]: get_ipython().run_line_magic('matplotlib', 'i ...

  4. UVA11294 Wedding

    嘟嘟嘟 大佬们都说这是2-SAT入门题,然而对于刚学2_SAT的本菜鸡来说半天才理解…… 题面:新娘和新郎不能坐在同一侧,妻子和丈夫不能坐在同一侧,有**关系的两个人必须至少一个坐在新娘一侧,问方案. ...

  5. 2018.9.16 Redis 边学习边总结

    Redis 是一个使用 C 语言写成的,开源的 key-value 数据库..和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合) ...

  6. CodeForces - 598A Tricky Sum (数学,快速幂的运用)

    传送门: http://codeforces.com/problemset/problem/598/A A. Tricky Sum time limit per test 1 second memor ...

  7. 1..net转java背景介绍

    注册博客2年了.从注册就开始接触.net.以前也有想过转java.只是没想过会这么快. .net语法这么优美好用.可惜了生态环境. .net还没有学成大神.就要离开了. 公司有个项目要用java.在加 ...

  8. 零基础Python知识点回顾(一)

    如果你是小白,建议只要安装官网的python-3.7.0-amd64.exe 然后在电脑cmd命令提示符  输入检查是否已经安装pip,一般安装了python都会有的. >pip         ...

  9. Navicat for Mysql中错误提示索引过长1071-max key length is 767 byte

    1.建用户信息表 tb_person_info create table tb_person_info( user_id int(10) auto_increment, `name` varchar( ...

  10. cefsharp作为采集工具(学习笔记)

    cefsharp(webkit内核)浏览器替代webbrowser用来采集页面数据. 需要在页面form加载完毕,用异步方式自动获取sourcecode. 由于国内cefsharp的资料相对比较少,在 ...