* Hash table based implementation of the <tt>Map</tt> interface.  This
* implementation provides all of the optional map operations, and permits
* <tt>null</tt> values and the <tt>null</tt> key. (The <tt>HashMap</tt>
* class is roughly equivalent to <tt>Hashtable</tt>, except that it is
* unsynchronized and permits nulls.) This class makes no guarantees as to
* the order of the map; in particular, it does not guarantee that the order
* will remain constant over time.

HashMap 继承自 接口Map. 这个实现类提供了接口Map所有的方法,并且允许空的value和空的key.
HashMap这个类 和类HashTable 类似,除了HashMap是异步的并且允许null值.
HashMap不保证map中元素的顺序,尤其,它不保证元素的顺序始终保持不变.

* <p>This implementation provides constant-time performance for the basic
* operations (<tt>get</tt> and <tt>put</tt>), assuming the hash function
* disperses the elements properly among the buckets. Iteration over
* collection views requires time proportional to the "capacity" of the
* <tt>HashMap</tt> instance (the number of buckets) plus its size (the number
* of key-value mappings). Thus, it's very important not to set the initial
* capacity too high (or the load factor too low) if iteration performance is
* important.

HashMap为基础操作(put,get)提供了 稳定的性能.
假设hash函数将元素适当的分散在桶(数组对象)中,迭代它需要和HashMap实例容量(capacity)及键值对数量(size)成比例的时间分配,
因此,初始化的时候,不宜将 容量(capacity)设置的太高或者太低很重要.

* <p>An instance of <tt>HashMap</tt> has two parameters that affect its
* performance: <i>initial capacity</i> and <i>load factor</i>. The
* <i>capacity</i> is the number of buckets in the hash table, and the initial
* capacity is simply the capacity at the time the hash table is created. The
* <i>load factor</i> is a measure of how full the hash table is allowed to
* get before its capacity is automatically increased. When the number of
* entries in the hash table exceeds the product of the load factor and the
* current capacity, the hash table is <i>rehashed</i> (that is, internal data
* structures are rebuilt) so that the hash table has approximately twice the
* number of buckets.

一个HashMap有两个参数(parameters):初始化容量(initial capacity)  +   负载因子(load factor);
初始化容量是指 HashMap实例的 数组的长度,负载因子 是一个测量指标,指当HashMap实例的size占容量的比例为多少时,自动扩增,导致容量(capacity)翻倍.

* <p>As a general rule, the default load factor (.75) offers a good
* tradeoff between time and space costs. Higher values decrease the
* space overhead but increase the lookup cost (reflected in most of
* the operations of the <tt>HashMap</tt> class, including
* <tt>get</tt> and <tt>put</tt>). The expected number of entries in
* the map and its load factor should be taken into account when
* setting its initial capacity, so as to minimize the number of
* rehash operations. If the initial capacity is greater than the
* maximum number of entries divided by the load factor, no rehash
* operations will ever occur.

通常,当负载因子为0.75时,会在时间和消耗中间取得一个较好的平衡.更高的负载因子虽然会减少空间开销,但会增加查找成本(反应在HashMap实例的大多数操作上面,包括get方法和put方法).
在设置初始化容量(initial capacity)时,应考虑map中元素的个数和 负载因子,尽量设置合理的初始化容量,这样能减少HashMap实例对象进行重新散列的操作次数.
如果初始化容量(initial capacity)比最大size(元素数)除以负载因子还大,那么永远不需要rehash(散列)操作.

* <p>If many mappings are to be stored in a <tt>HashMap</tt>
* instance, creating it with a sufficiently large capacity will allow
* the mappings to be stored more efficiently than letting it perform
* automatic rehashing as needed to grow the table. Note that using
* many keys with the same {@code hashCode()} is a sure way to slow
* down performance of any hash table. To ameliorate impact, when keys
* are {@link Comparable}, this class may use comparison order among
* keys to help break ties.

如果大量的键值对存储在HashMap实例中,设置足够大的初始化容量(initial capacity)比 不设置初始化容量(initial capacity),让HashMap实例自动扩增,更加高效.
请注意,大量使用key的散列值(hashCode())一样的键值对 会降低 对该对实例的操作效率.为了改善这种影响,key最好能实现Comparable接口,这个类能够降低这种影响.

* <p><strong>Note that this implementation is not synchronized.</strong>
* If multiple threads access a hash map concurrently, and at least one of
* the threads modifies the map structurally, it <i>must</i> be
* synchronized externally. (A structural modification is any operation
* that adds or deletes one or more mappings; merely changing the value
* associated with a key that an instance already contains is not a
* structural modification.) This is typically accomplished by
* synchronizing on some object that naturally encapsulates the map.

请注意这个实现(HashMap)不  是异步的.如果大量线程同时使用一个hashMap实例,最少会有一个线程会修改这个hashMap实例的结构.
因此,它需要增加额外的异步封装(一个结构性的修改包含任何增加或者删除键值对的操作,仅仅修改已有的一个键值对的值,并不算是结构性的修改),
这通常是在一些自然封装map的对象的异步完成.

* If no such object exists, the map should be "wrapped" using the
* {@link Collections#synchronizedMap Collections.synchronizedMap}
* method. This is best done at creation time, to prevent accidental
* unsynchronized access to the map:<pre>
* Map m = Collections.synchronizedMap(new HashMap(...));</pre>

如果这样的对象并不存在,map对象就应该使用Collections.synchronizedMap {@link Collections#synchronizedMap Collections.synchronizedMap}方法 来进行包裹.
这个操作最好在创建Map对象时进行,防止对这个Map对象进行了意外的非阻塞的操作.   (例:Map m = Collections.synchronizedMap(new HashMap(...));)

* <p>The iterators returned by all of this class's "collection view methods"
* are <i>fail-fast</i>: if the map is structurally modified at any time after
* the iterator is created, in any way except through the iterator's own
* <tt>remove</tt> method, the iterator will throw a
* {@link ConcurrentModificationException}. Thus, in the face of concurrent
* modification, the iterator fails quickly and cleanly, rather than risking
* arbitrary, non-deterministic behavior at an undetermined time in the
* future.

迭代器将会被该类的集合视图方法返回是 fail-fast机制,
fail-fast机制:如果这个map对象在创建迭代器后的任何时间里发生了结构性改变(除了迭代器 remove 的方式外),这个迭代器将会抛出异常({@link ConcurrentModificationException}),
因此,当面对多线程同事对map对象进行修改操作时,迭代器将会快速简洁的失败,而不是冒着在未来的某个不确定的时间里产生不确定性影响的风险.

* <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
* as it is, generally speaking, impossible to make any hard guarantees in the
* presence of unsynchronized concurrent modification. Fail-fast iterators
* throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
* Therefore, it would be wrong to write a program that depended on this
* exception for its correctness: <i>the fail-fast behavior of iterators
* should be used only to detect bugs.</i>

请注意, 迭代器的fail-fast机制不能被保证,一般来说,迭代器在进行异步的结构修改操作中,不能做出任何确定的保证.当发生Fail-fast时,迭代器将会尽量抛出异常(ConcurrentModificationException),
因此,我们在代码中不能依赖这个异常(ConcurrentModificationException)来确保代码的正确性.
迭代器的fail-fast机制应该被用来进行bug的探测.

hashMap源码分析1--翻译的更多相关文章

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

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

  2. Java中HashMap源码分析

    一.HashMap概述 HashMap基于哈希表的Map接口的实现.此实现提供所有可选的映射操作,并允许使用null值和null键.(除了不同步和允许使用null之外,HashMap类与Hashtab ...

  3. JDK1.8 HashMap源码分析

      一.HashMap概述 在JDK1.8之前,HashMap采用数组+链表实现,即使用链表处理冲突,同一hash值的节点都存储在一个链表里.但是当位于一个桶中的元素较多,即hash值相等的元素较多时 ...

  4. HashMap源码分析和应用实例的介绍

    1.HashMap介绍 HashMap 是一个散列表,它存储的内容是键值对(key-value)映射.HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io.S ...

  5. 【Java】HashMap源码分析——常用方法详解

    上一篇介绍了HashMap的基本概念,这一篇着重介绍HasHMap中的一些常用方法:put()get()**resize()** 首先介绍resize()这个方法,在我看来这是HashMap中一个非常 ...

  6. 【Java】HashMap源码分析——基本概念

    在JDK1.8后,对HashMap源码进行了更改,引入了红黑树.在这之前,HashMap实际上就是就是数组+链表的结构,由于HashMap是一张哈希表,其会产生哈希冲突,为了解决哈希冲突,HashMa ...

  7. Java BAT大型公司面试必考技能视频-1.HashMap源码分析与实现

    视频通过以下四个方面介绍了HASHMAP的内容 一. 什么是HashMap Hash散列将一个任意的长度通过某种算法(Hash函数算法)转换成一个固定的值. MAP:地图 x,y 存储 总结:通过HA ...

  8. Java源码解析——集合框架(五)——HashMap源码分析

    HashMap源码分析 HashMap的底层实现是面试中问到最多的,其原理也更加复杂,涉及的知识也越多,在项目中的使用也最多.因此清晰分析出其底层源码对于深刻理解其实现有重要的意义,jdk1.8之后其 ...

  9. HashMap源码分析(史上最详细的源码分析)

    HashMap简介 HashMap是开发中使用频率最高的用于映射(键值对 key value)处理的数据结构,我们经常把hashMap数据结构叫做散列链表: ObjectI entry<Key, ...

  10. HashMap 源码分析 基于jdk1.8分析

    HashMap 源码分析  基于jdk1.8分析 1:数据结构: transient Node<K,V>[] table;  //这里维护了一个 Node的数组结构: 下面看看Node的数 ...

随机推荐

  1. 单片机pwm控制基本原理详解

    前言 PWM是Pulse Width Modulation的缩写,它的中文名字是脉冲宽度调制,一种说法是它利用微处理器的数字输出来对模拟电路进行控制的一种有效的技术,其实就是使用数字信号达到一个模拟信 ...

  2. 洛谷P4219 大融合

    LCT新姿势:维护子树信息. 不能带修,子树修改就要toptree了... 题意:动态加边,求子树大小. 解: 维护子树信息只要额外维护虚边连的儿子的信息即可.这里把siz的定义变成子树大小. 哪里会 ...

  3. A1142. Maximal Clique

    A clique is a subset of vertices of an undirected graph such that every two distinct vertices in the ...

  4. [ZROJ110][假如战争今天爆发]

    题面 思路 先假设我们已经知道了操作顺序,考虑如何求出时间.用f[i][j]表示前i个物品,第i个加工完了第j台机器所需要的最少的时间.转移的时候就是f[i][j] = max(f[i-1][j],f ...

  5. 一文看懂npm、yarn、pnpm之间的区别

    文作者对比了当前主流的包管理工具npm.yarn.pnpm之间的区别,并提出了合适的使用建议,以下为译文: NPM npm是Node.js能够如此成功的主要原因之一.npm团队做了很多的工作,以确保n ...

  6. 第五节,TensorFlow编程基础案例-session使用(上)

    在第一节中我们已经介绍了一些TensorFlow的编程技巧;第一节,TensorFlow基本用法,但是内容过于偏少,对于TensorFlow的讲解并不多,这一节对之前的内容进行补充,并更加深入了解讲解 ...

  7. pytest 8 参数化parametrize

    pytest.mark.parametrize装饰器可以实现用例参数化 1.以下是一个实现检查一定的输入和期望输出测试功能的典型例子 import pytest @pytest.mark.parame ...

  8. python学习笔记-列表和字典

    由于最近在看深度学习的代码,看到需要建立字典和列表来存储什么东西的时候,就想要去把字典和列表好好的了解清楚,其应用范围,差别,等等东西 首先我们来介绍,在python中存在如下的数据结构:列表list ...

  9. (BFS 二叉树) leetcode 515. Find Largest Value in Each Tree Row

    You need to find the largest value in each row of a binary tree. Example: Input: 1 / \ 3 2 / \ \ 5 3 ...

  10. python自动化开发-[第十二天]-前端html

    今日概要: 前端基础之html 1.web服务器的本质: #!/usr/bin/python # -*- coding:utf-8 -*- import socket def handle_reque ...