HashMap笔记

集合

HashMap

这是HashMap的源码注释文档翻译,我觉得源码的注释文档写的很详细,也很通俗易懂。

基于哈希表的Map接口实现。此实现提供所有可选的映射操作,并允许 空值和空键。(HashMap 类大致相当于Hashtable,除了它是不同步的并且允许空值。)这个类不保证MAP的顺序; 特别是,它不保证顺序会随着时间的推移保持不变。

假设散列函数在桶之间正确地分散元素,该实现为基本操作(get和put)提供了恒定时间性能。对集合视图的迭代需要与HashMap实例的“容量” (桶的数量)加上其大小(键 - 值映射的数量)成比例的时间 。因此,如果迭代性能很重要,则不要将初始容量设置得太高(或负载因子太低)非常重要。

HashMap的一个实例有两个影响其性能的参数:初始容量和负载因子。容量是在哈希表中桶的数量,初始容量是创建hash表的容量。负载因子是哈希表在增加之前允许的最大容量。当哈希表中的条目数超过加载因子和当前容量的乘积时,哈希表将被重新哈希(即,重建内部数据结构),以便哈希表具有大约两倍的桶数。

作为一般规则,默认加载因子(.75)在时间和空间成本之间提供了良好的折衷。较高的值会减少空间开销,但会增加查找成本(反映在HashMap类的大多数操作中,包括 get和put)。在设置其初始容量时,应考虑映射中的预期条目数及其负载因子,以便最小化重新散列操作的数量。如果初始容量大于最大条目数除以加载因子,则不会发生重新加载操作。

如果要将多个映射存储在HashMap 实例中,则使用足够大的容量创建映射将允许映射更有效地存储,而不是根据需要执行自动重新散列来扩展表。请注意,**很多keys有相同的hashCode()是降低任何哈希表性能的可靠方法。(意思就是不要让很多key具有相同的hashCode)**为了降低这种情况(许多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。因此,编写依赖于此异常的程序的做法是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测程序错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值