HashMap源码分析

要想理解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接口的实现。这个实现提供了所有可选的映射操作,并允许null值和null键。(HashMap类大致等同于Hashtable,只是它是不同步的,并且允许为null。)这个类对映射的顺序不做任何保证;特别是,它不能保证顺序随着时间的推移保持不变。

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.

这个实现为基本操作(getput)提供恒定的时间性能,假设散列函数在bucket中适当地分散元素。集合视图上的迭代所需的时间与HashMap实例的“容量”(bucket的数量)加上其大小(键值映射的数量)成比例。因此,如果迭代性能很重要,那么不要将初始容量设置得太高(或者负载系数太低),这一点非常重要。

An instance of HashMap has two parameters that affect its performance: initial capacity and load factor. Thecapacity 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 load factor 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 rehashed (that is, internal data structures are rebuilt) so that the hash table has approximately twice the number of buckets.

HashMap的实例有两个影响其性能的参数:初始容量负载因子。capacity是哈希表中的bucket数,初始容量就是哈希表创建时的容量。loadfactor是一个度量哈希表在其容量自动增加之前可以达到的完整程度。当哈希表中的条目数超过加载因子与当前容量的乘积时,哈希表将被重新哈希化(即重建内部数据结构),因此哈希表的存储桶数大约是原来的两倍。

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.

一般来说,默认的负载系数(.75)在时间和空间成本之间提供了很好的折衷。较高的值会减少空间开销,但会增加查找成本(反映在HashMap类的大多数操作中,包括getput)。在设置初始容量时,应考虑map中的预期条目数及其荷载系数,以尽量减少再灰化操作的次数。如果初始容量大于最大入口数除以负载系数,则不会发生再吹灰操作。

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. 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实例中,那么创建一个足够大的容量将使映射得到更有效的存储,而不是让它根据需要执行自动重洗以增加表。请注意,使用具有相同{@code hashCode()}的多个键是降低任何哈希表性能的可靠方法。为了改善影响,当键是{@link Comparable}时,这个类可以使用键之间的比较顺序来帮助打破联系。

Note that this implementation is not synchronized. If multiple threads access a hash map concurrently, and at least one of the threads modifies the map structurally, it must 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. 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:

 Map m = Collections.synchronizedMap(new HashMap(...));

注意,这个实现是不同步的。如果多个线程同时访问一个哈希映射,并且至少有一个线程在结构上修改了该映射,则它必须在外部同步。(结构修改是指添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键相关联的值不是结构修改。)这通常是通过对自然封装映射的对象进行同步来完成的。 如果不存在这样的对象,则应该使用{@link Collections\synchronizedMap对映射进行“包装”集合.synchronizedMap}方法。最好在创建时执行此操作,以防止意外的不同步访问映射:

map m=集合.synchronizedMap(新的HashMap(…);

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 {@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:如果在迭代器创建之后的任何时候,以任何方式(除了通过迭代器自己的remove方法)对映射进行结构修改,迭代器将抛出一个{@link ConcurrentModificationException}。因此,在并发修改的情况下,迭代器会迅速而彻底地失败,而不是在将来某个不确定的时间冒着任意的、不确定的行为的风险。

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.

注意,迭代器的fail-fast行为不能得到保证,因为一般来说,在存在不同步的并发修改时,不可能做出任何硬保证。Fail fast迭代器尽最大努力抛出ConcurrentModificationException。因此,编写一个依赖于这个异常来保证其正确性的程序是错误的:迭代器的快速失效行为应该只用于检测错误。

时间原因,我之前网上看到有个人对HashMap源码解析的挺好的,直接引用过来学习。

https://www.jianshu.com/p/84cfc4e55a3c

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值