Java源码解析HashMap简介

网友投稿 218 2023-01-15


Java源码解析HashMap简介

本文基于jdk1.8进行分析

HashMap是java开发中可以说必然会用到的一个集合。本文就HashMap的源码实现进行分析。

首先看一下源码中类的javadoc注释对HashMap的解释。如下图。HashMap是对Map接口的基于hash表的实现。这个实现提供了map的所有可选操作,并且允许nullqjbIyU值(可以多个)和一个null的key(仅限一个)。HashMap和HashTable十分相似,除了HashMap是非同步的且允许null元素。这个类不保证map里的顺序,更进一步,随着时间的推移,它甚至不保证顺序一直不变。

这个实现为get和put这样的基本操作提供常量级性能,它假设hash函数把元素们比较好的分散到各个桶里。用迭代器遍历集合需要的时间,和HashMap的容量与HashMap里的Entry数量的和成正比。所以,如果遍历性能很重要的话,一定不要把初始容量设置的太大,或者把负载因子设置的太小。

一个hashmap有两个影响它的性能的参数,初始容量和负载因子。容量是哈希表中桶的数量,初始容量就是创建哈希表时桶的数量。负载银子是哈希表的容量自动扩容前哈希表能够达到多满。当哈希表中条目的数量超过当前容量和负载因子的乘积后,哈希表会进行重新哈希(也就是,内部数据结构重建),以使哈希表大约拥有2倍数量的桶。

作为一个通常的规则,默认负载银子(0.75) 提供了一个时间和空间的比较好的平衡。更高的负载因子会降低空间消耗但是会增加查找的消耗。当设置初始容量时,哈希表中期望的条目数量和它的负载因子应该考虑在内,以尽可能的减小重新哈希的次数。如果初始容量比条目最大数量除以负载因子还大,那么重新哈希操作就不会发生。

如果许多entry需要存储在哈希表中,用能够容纳entry的足够大的容量来创建哈希表,比让它在需要的时候自动扩容更有效率。请注意,使用多个hash值相等的key肯定会降低任何哈希表的效率。

请注意这个实现不是同步的。如果多个线程同时访问哈希表,并且至少有一个线程会修改哈希表的结构,那么哈希表外部必须进行同步。

/**

* 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.

*

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.

*

An instance of HashMap has two parameters that affect its

* performance: initial capacity and load factor. The

* capacity is the number of buckets in the hash table, and the initial

* capacity is shttp://imply 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 oqjbIyUf 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.

*

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.

*

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.

*

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(...));

*

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.

*

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.

*

This class is a member of the

*

* Java Collections Framework.

* @param the type of keys maintained by this map

* @param the type of mapped values

* @author Doug Lea

* @author Josh Bloch

* @author Arthur van Hoff

* @author Neal Gafter

* @see Object#hashCode()

* @see Collection

* @see Map

* @see TreeMap

* @see Hashtable

* @since 1.2

**/

This is the end。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。如果你想了解更多相关内容请查看下面相关链接


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Spring的AOP极简入门
下一篇:Java可重入锁的实现原理与应用场景
相关文章

 发表评论

暂时没有评论,来抢沙发吧~