源碼分析——HashMap初始化

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源碼

JDK1.8HashMap官網

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章