HashMap类的注释翻译(jdk1.8)

  基于Hash Table(哈希表)的Map接口实现。这个实现提供了所有可选的映射操作,并允许key和value为null。(HashMap大致相当于HashTable类,不同的是非同步和允许空值)。HashMap不保证Map的顺序(即,存储顺序跟put顺序不一致);而且,不保证这个顺序不发生变化(当rehash时,和可能发生变化)。

  HashMap对基本操作(put、get)提供了常量级实现,假设hash函数能够将元素均匀分布在不同的桶中。迭代操作的时间性能取决于HashMap实例的容量(capacity,桶的数量)和他的size(Key-Value映射的数量)。这样,如果对迭代性能要求比较高的话,不要将容量capacity设置的过高(或者,装载因子不要太低。因为装载因子越低,空桶数量越多;如果装载因子太高,可能会发生碰撞,导致一个桶后面有很多元素,要么使用链表实现,要么使用红黑树实现)。

  初始化的容量capacity和装载因子load factor这两个参数会影响HashMap实例的性能。容量是指hash表中桶的数量,容量的初始值就是hash表被创建时的容量。 装载因子是用来衡量hash表满的程度。当hash表中entry(表项)的数量超过了容量与装载因子的乘积,hash表就会rehash(也就是说,内部的数据结构会重建),导致hash表的桶数量翻倍。

  通常的规则,0.75(使用hash表桶的3/4)这个装载因子会在时间性能和空间开销之间达到一个平衡。高的装载因子虽然能够降低空间开销,但是却增加了查找开销(反映在HashMap的大多数操作上,包括put和get)。当设置初始的容量时,要考虑预计放进map中的表项的数量和装载因子,以降低rehash操作的次数。如果初始的容量比预计的entry数量除以装载因子的商还要大,那么永远不需要rehash操作。

  如果要往HashMap实例中存放很多K-V映射,创建这个实例时就给足够大的容量,这要比按需rehash的性能要高。千万不要让很多key具有相同的hashCode,这会降低hash表的性能。为了降低这种情况(许多Key具有相同的hashCode)的影响,Key最好能够实现Comparable接口,这样这个类就能在这些key之间使用比较来降低这种影响。

  注意,这个HashMap的实现不是同步的。如果有多个线程并发的访问hashMap, 至少有一个线程结构化的修改map,他必须要在外部同步。(所谓结构化修改是指,任何添加或删除一个或多个KV映射,仅仅改变一个实例已经有的KV映射的值不是结构性修改)。这通常是通过同步封装在这个map上的某个对象来是实现的。

  如果没有这样的对象(包含map的对象)存在,这个map应该使用Collections#synchronizedMap来封装。为了防止偶然异步访问这个map,最后在创建的时候就这么干:
Map m = Collections.synchronizedMap(new HashMap(…));

  当迭代器创建之后,除了通过迭代器自己的remove方法,任何对map进行了结构性修改,迭代器就会抛出 并发修改的异常。当面对并发修改的时候,迭代器会快速明了的报错,而不冒任何在未来的某个不确定时间的不确定行为的风险。
注意,迭代器的快速失败行为不能得到保证,一般来说,存在非同步的并发修改时,不可能作出任何坚决的保证。快速失败迭代器尽最大努力抛出 ConcurrentModificationException。因此,编写依赖于此异常的程序的做法是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测程序错误。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值