文档章节

HashMap , 翻译解释

ol_O_O_lo
 ol_O_O_lo
发布于 06/14 19:15
字数 2121
阅读 4
收藏 0
点赞 0
评论 0

JDK1.7版本的HASHMAP
HashMap文件头注释翻译:

Hash table based implementation of the Map interface. This implementation provides all of the optional map operations, and permits null values and the null key. (The HashMap class is roughly equivalent to Hashtable, 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.
↓↓↓↓↓
基于Map接口实现的Hash表 , 提供了map的所有可选操作 , 并且允许多个值(value)为null,一个键(key)为null. [HashMap基本类似于HashTable,除了非线程安全(unsynchronized)和允许null] . 这个类不能保证map的顺序[1],特殊说明,随着时间推移,不保证map的顺序不变[2]

[1] . map是无序的. 跟put顺序没关系.
[2] .

  • hashmap的每次put都在去判断是否需要resize,
  • resize操作时,会收集系统信息,判断是否需要调整计算hash的性能(hashseed),
  • 如果需要,hashseed会不同,
  • 那么计算的hash值也不同.
  • 那么key落在的位置也不同.
  • 那么举例就是,hashseed=0时计算hash为A在前,B在后.hashseed=1时,计算hash为B在前,A在后.
  • 那么可得,迭代器迭代的也是完全无序的,可以理解为乱序.

 

This implementation provides constant-time performance for the basic operations (get and put), assuming the hash function disperses the elements properly among the buckets. Iteration over collection views requires time proportional to the "capacity" of the HashMap 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.
↓↓↓↓↓
本类提供的基础操作性能恒定(constant-time performance)[get和put操作],可以认为散列函数在桶中均匀的分散元素.[3]
迭代器(Iterator)迭代集合所需要的时间与HashMap实例的"容量[桶的数量]"成正比,再加上其大小[键值对的数量][4].
因此,如果需要迭代器的性能,就不要设置太高的初始容量(initial capacity)(或者太低的负载因子(load factor))[5]

[3] . 性能恒定的说法是有一定前提的.(单指get和put操作)

  1. 负载因子(load factor)适当,默认的0.75在多数场景下是比较OK的.太高,会有hash冲突,太低则浪费空间.
  2. 不触发扩容. 扩容相对来说是比较耗时的操作.所以就需要在初始化时,尽量准确的提供初始容量.后续就会尽量少的触发扩容操作.
  3. 在上两个适当的情况下.散列算法基本会将key均匀分布在数组中,无论数据量有多大,那么get和put都是直接寻址,快速,性能好.

[4] . 容量(capacity)和大小(size)是两个概念 .

  1. 容量(capacity)是初始化数组的个数,举例:默认初始容量是16,就算没有put数据,容量还是16.
  2. 大小(size),在没有put数据时,size为0,put一个数据,size为1.等等.
  3. so~ ,没有数据时, capacity=16 , size=0 , put一次后, capacity=16 , size=1 .
  4. so~ ,迭代器(iterator)是按容量去循环,再加每个容量里链的长度. 所以就算size=1,iterator循环16次.
1HashIterator() {
2    expectedModCount = modCount;
3    if (size > 0) { // advance to first entry
4        Entry[] t = table;
5        //循环查询hash表,直到不为null的数据存在,并赋值给next
6        while (index < t.length && (next = t[index++]) == null);
7    }
8}

[5] . 官方建议,容量不要太大,合适就行;负载因子(load factor)太低,也会造成容量过大,实际使用较小.不然迭代器在要做太多无用功.

感觉自己的翻译还是太差了,比较吃力,自己可以看的懂,但解释不出来….,还是只贴原文吧

 

An instance of HashMap has two parameters that affect its performance: initial capacity and load factor.[6] The capacity 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.[7] The load factor is a measure of how full the hash table is allowed to get before its capacity is automatically increased.[8] When the number of entries in the hash table exceeds the product of the load factor and the current capacity, the hash table is rehashed (that is, internal data structures are rebuilt) so that the hash table has approximately twice the number of buckets.[9]

[6] . HashMap有两个特别重要的性能指标:初始容量(initial capacity)和负载因子(load factor)
[7] . 容量(capacity),就是hash表里桶的数量(桶==key数组),初始容量就是hashmap在创建时的指定的一个容量,不是实际容量.(实际容量会在实际put时计算,实际容量=MAX(2n,initialCapacity),最接近初始容量的一个2的幂值,比如初始容量=20,那么实际容量=32)
[8] . 负载因子(load factor),调节hashMap性能的重要参数
loadFactor<=>capacitysize​,当比例值大于等于loadFactor,则触发扩容,.比例值小于loadFactor,put时不触发扩容.
[9] . size>=capacity∗loadFactor ,触发扩容,会重新进行hash计算(内部数据结构被重建).扩容后的容量是原容量的2倍,即:2∗capacity

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 HashMap class, including get and put). 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.[10]

[10] . 这段就重点说下负载因子(load factor). 默认的0.75,是在时间和空间成本上取了个折中;较大的值的话,虽然减少了空间浪费,增大了hash冲突的概率,增大了链表的长度.增大了查找的成本.
所以在设置初始容量的时候,考虑好数据量和负载因子,尽量减少重新散列(rehash)操作的次数.

If many mappings are to be stored in a HashMap 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.[11]

[11] . 如果你需要在map中存储大量数据,那么一个足够大的初始容量才是最好的,避免扩容操作.

重点来了!
Note that this implementation is not synchronized.[12] If multiple threads access a hash map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally.[13] (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.[14]

[12] . 本实现类不是线程安全的
[13] . 如果有多个线程要访问hashMap,并且至少有一个线程要修改数据结构,那么就必须要做线程同步.(修改操作包括:put,putAll,remove等).
[14] . 通常是在对象上加同步锁 (synchroniz) 来实现同步操作.

If no such object exists, the map should be "wrapped" using the Collections.synchronizedMap method. This is best done at creation time, to prevent accidental unsynchronized access to the map:Map m = Collections.synchronizedMap(new HashMap(...));[15]

[15] . 可以用Collections.synchronizedMap来包含对象,使其成为线程同步对象.最好的创建对象的时候,就包含起来.
这是硬操作,把hashmap用synchronized关键字包裹.性能不好,同步可以用concurrenthashmap

The iterators returned by all of this class's "collection view methods" are fail-fast: if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will throw a 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.[16]

[16] . 迭代器(iterator)的快速失败(fail-fast)原则: 在多线程的时候,一个线程在迭代,另一个线程修改了结构(put,putAll,remove).那么会抛出ConcurrentModificationException异常.退出迭代.除非是iterator自己的remove方法.
场景疑问:A,B两个线程都在迭代map,A线程iterator.remove了.B线程会不会抛异常??

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 ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.

  • 上一段说的挺好,这一段又开始尥蹶子了.
  • 意思是多线程操作发生 时,不能保证一定会有异常抛出(即快速失败行为).多线程操作的时候,谁都保证不了.
  • iterator已经尽最大努力去抛出异常ConcurrentModificationException.所以不能依赖这些个异常去做决断.只是提供一个参考.(你地明白…)

到此结束.打完收功!

© 著作权归作者所有

共有 人打赏支持
ol_O_O_lo
粉丝 0
博文 22
码字总数 7149
作品 0
杭州
高级程序员
[转]为什么Java中的String不可变

笔主前言: 众所周知,String是Java的JDK中最重要的基础类之一,在笔主心中的地位已经等同于int、boolean等基础数据类型,是超越了一般Object引用类型的高端大气上档次的存在。 但是稍有研究...

gagabear ⋅ 2014/09/23 ⋅ 0

从源码来聊一聊hashmap

前段时间一同事面试蚂蚁金服,就被问到了这个问题;其实很多情况下都是从hashMap,hashTable,ConcurrentHahMap三者之间的关系衍生而出,当然也有直接就针对hashMap原理直接进行考察的。实际上...

glmapper ⋅ 2017/12/03 ⋅ 0

Java集合框架知识及HashMap和HashSet的区别

HashMap和HashSet的区别 HashSet实质 (1)HashSet是set的一个实现类,hashMap是Map的一个实现类,同时hashMap是hashTable的替代品(为什么后面会讲到). (2)HashSet以对象作为元素,而HashMap以(ke...

qq_36523667 ⋅ 03/17 ⋅ 0

如何线程安全的使用HashMap

为什么HashMap是线程不安全的 总说HashMap是线程不安全的,不安全的,不安全的,那么到底为什么它是线程不安全的呢?要回答这个问题就要先来简单了解一下HashMap源码中的使用的存储结构(这里...

Edwyn王 ⋅ 2016/09/02 ⋅ 0

HashMap vs ConcurrentHashMap — 示例及Iterator探秘

如果你是一名Java开发人员,我能够确定你肯定知道ConcurrentModificationException,它是在使用迭代器遍历集合对象时修改集合对象造成的(并发修改)异常。实际上,Java的集合框架是迭代器设...

恶魔永生 ⋅ 2015/01/30 ⋅ 0

Java Hashtable factor 0.75

今天在看spring源码是,发现有一处代码是这样写的(代码位置3.0.5 package org.springframework.jndi下JndiTemplate 129行): protected Context createInitialContext() throws NamingExce......

Hero_Q ⋅ 2012/01/16 ⋅ 0

跨平台移动应用方法--JUniversal

JUniversal 是基于 Java 的跨平台移动应用方法。 JUniversal 与 Xamarin 和 Cordova 在内的多种方案比较 JUniversal的构想来自诺基亚的几个开发者,他们在 Java 和构建跨平台应用方面具备相当...

叶秀兰 ⋅ 2015/02/02 ⋅ 0

HashMap map = new HashMap();

HashMap map = new HashMap(); 这句话对吗?如果错误,为什么?一般应该改成什么样?请稍微解释一下

成王败寇 ⋅ 2013/05/08 ⋅ 5

ListView的多选

项目过程中,常常会遇到多选列表的问题。问题不麻烦,但似乎每一次的实现都不一样,或者说不规范吧。之前一直使用的HashMap来记录列表的选中情况,但心中一直惦记着其使用SparseBooleanArra...

一剑围城 ⋅ 2017/06/06 ⋅ 0

HashMap中傻傻分不清楚的那些概念

很多人在通过阅读源码的方式学习Java,这是个很好的方式。而JDK的源码自然是首选。在JDK的众多类中,我觉得HashMap及其相关的类是设计的比较好的。很多人读过HashMap的代码,不知道你们有没有...

⋅ 05/20 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Linux中的端口大全

1 被LANA定义的端口 端口 名称 描述 1 tcpmux TCP 端口服务多路复用 5 rje 远程作业入口 7 echo Echo 服务 9 discard 用于连接测试的空服务 11 systat 用于列举连接了的端口的系统状态 13 d...

寰宇01 ⋅ 12分钟前 ⋅ 0

Confluence 6 如何备份存储文件和页面信息

备份的 ZIP 文件包含有 entities.xml,这个 XML 文件包含有 Confluence 的所有页面内容和存储附件的目录。 备份 Zip 文件结构 页面的附件是存储在附件存储目录中的,通过页面和附件 ID 进行识...

honeymose ⋅ 15分钟前 ⋅ 0

【每天一个JQuery特效】根据状态确定是否滑入或滑出被选元素

主要效果: 本文主要采用slideToggle()方法实现以一行代码同时实现以展开或收缩的方式显示或隐藏被选元素。 主要代码如下: <!DOCTYPE html><html><head><meta charset="UTF-8">...

Rhymo-Wu ⋅ 19分钟前 ⋅ 0

度量.net framework 迁移到.net core的工作量

把现有的.net framework程序迁移到.net core上,是一个非常复杂的工作,特别是一些API在两个平台上还不能同时支持。两个类库的差异性,通过人工很难识别全。好在微软的工程师们考虑到了我们顾...

李朝强 ⋅ 24分钟前 ⋅ 0

请不要在“微服务”的狂热中迷失自我!

微服务在过去几年一直是一个非常热门的话题(附录1)。何为“微服务的疯狂”,举个例子: 众所周知,Netflix在DevOps上的表现非常棒。Netfix可以做微服务。因此:如果我做微服务,我也将非常...

harries ⋅ 26分钟前 ⋅ 0

oAuth2 升级Spring Cloud Finchley.RELEASE踩坑分享

背景 6.19号,spring团队发布了期待已久的 Spring Cloud Finchley.RELEASE 版本。 重要变化: 基于Spring Boot 2.0.X 不兼容 Spring Boot 1.5.X 期间踩过几个坑,分享出来给大伙,主要是关于...

冷冷gg ⋅ 55分钟前 ⋅ 0

OSChina 周一乱弹 —— 理发师小姐姐的魔法

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @冰冰棒- :分享田馥甄的单曲《My Love》 《My Love》- 田馥甄 手机党少年们想听歌,请使劲儿戳(这里) @Li-Wang :哎,头发又长了。。。又要...

小小编辑 ⋅ 今天 ⋅ 8

Kafka1.0.X_消费者API详解2

偏移量由消费者管理 kafka Consumer Api还提供了自己存储offset的功能,将offset和data做到原子性,可以让消费具有Exactly Once 的语义,比kafka默认的At-least Once更强大 消费者从指定分区...

特拉仔 ⋅ 今天 ⋅ 0

NEO智能合约之发布和升级(二)

接NEO智能合约之发布和升级(一),我们接下来说说智能合约的升级功能。 一 准备工作 合约的升级需要在合约内预先设置好升级接口,以方便在升级时调用。接下来我们对NEO智能合约之发布和升级...

红烧飞鱼 ⋅ 今天 ⋅ 0

个人博客的运营模式能否学习TMALL天猫质量为上?

心情随笔|个人博客的运营模式能否学习TMALL天猫质量为上? 中国的互联网已经发展了很多年了,记得在十年前,个人博客十分流行,大量的人都在写博客,而且质量还不错,很多高质量的文章都是在...

原创小博客 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部