What is 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接口的实现。此实现提供了所有可选的map操作,并允许null 值和 null 键。 ( HashMap 类跟Hashtable类似,除了它是不同步的并且允许空值。)这个类不保证map的顺序;尤其是,它不保证顺序会随着时间的推移保持不变。HashMap的结构是Entry数组+链表的形式。
HashMap初始化
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 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 ehashed (that is, internal data structures are rebuilt) so that the hash table has approximately twice the number of buckets.
HashMap的一个实例有两个影响其性能的参数:初始容量和负载因子。容量是哈希表中的桶数,初始容量只是创建哈希表时桶的容量。该负载因子是在自动扩容之前桶的填满程度比例。当哈希表中的条目数超过负载因子和当前容量的乘积时,哈希表将被ehashed (即,重建内部数据结构),以便哈希表几乎具有两倍桶数。
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 vided by the load factor, no rehash operations will ever occur.
作为一般规则,负载因子默认(.75)在时间和空间成本之间做了良好的权衡。负载因子,更大的值会减少空间开销,但会增加查找成本(反映在HashMap类的大多数操作中,包括get和put)。在设置其初始容量时,应考虑map中的预期条目数及其负载因子,以便最小化rehash操作的数量。如果初始容量大于由负载因子提供的最大条目数,则不会发生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. 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实例中,则使用足够大的容量容纳映射关系并且有效地存储,而不是根据需要执行自动rehash来扩展表。请注意,很多key采用相同的{@code hashCode()}方法,肯定会降低哈希表性能。为了改善影响,当方法为{@link Comparable}时,此类可以使用keys之间的顺序比较来帮助打破关系。
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.
请注意,此实现不同步。如果多个线程同时访问HashMap,并且至少有一个线程在结构上修改了map,则必须在外部进行同步。 (结构修改是添加或删除一个或多个映射的操作;仅更改实例的键值不是结构修改。)通常通过同步某些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:<pre> Map m = Collections.synchronizedMap(new HashMap(…));</pre>
如果不存在此类对象,则应使用{@link Collections.synchronizedMap}方法“包装”该map。这最好在创建时完成,以防止意外地不同步访问map。
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:如果map在迭代器创建后的任何时间进行结构修改,除非通过迭代器自己移除操作,否则迭代器会抛出一个{@link ConcurrentModificationException}。因此,面对并发修改,迭代器fail-fast,好过在一个不确定的时间内的不确定行为。
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行为无法得到保证,因为一般来说,在存在不同步的并发修改时,不可能做出任何硬性保证。失败快速迭代器会尽最大努力抛出ConcurrentModificationException。因此,编写依赖于此异常的程序以确保其正确性是错误的:迭代器的 fail-fast 行为应该仅用于检测错误。
HashMap初始化的时候,默认大小为16,负载因子为0.75。
HashMap map = new HashMap();
//HashMap无参构造函数
/**
* Constructs an empty <tt>HashMap</tt> with the default initial capacity
* (16) and the default load factor (0.75).
*/
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
参考资料:
JDK1.8源码