HashMap

   HashMap是基於哈希表的Map接口的非同步實現。此實現提供全部可選的映射操做,並容許使用null值和null鍵。此類不保證映射的順序,特別是不能保證該順序恆久不變。java

   HashMap的數據結構:算法

   在java中,最基本的結構有兩種:一是數組,而是模擬指針(引用),全部的數據結構均可以用這兩個基本結構來構造。HashMap其實是一個「鏈表散列」的數據結構,即數組和鏈表的結合體。數組

  

HashMap底層就是一個數組結構,數組中的每一項又是一個鏈表。當新建一個HashMap時,就會初始化一個數組。數據結構

1 transient Entry[] table;
2 static class Entry<k,V> implements Map.Entry<K,V>{
3     final K key;
4     V value;
5     Entry<K,V> next;
6     final int hash;
7     ......
8 }

能夠看出,Entry就是數組中的元素,每一個Map.Entry其實就是一個key-value對,它持有一個指向下一個元素的引用,這就構成了鏈表。性能

  HashMap的存取實現:this

  1)存儲:spa

 1 public V put(K key,V value){
 2     //HashMap容許存放null值和null鍵
 3     //當key爲null時,調用putForNullKey方法,將value放置在數組的一個位置。
 4     if(key==null)
 5         return putForNullKey(value);
 6     //根據key的hashCode從新計算hash值
 7     int hash=hash(key.hashCode());
 8     //搜索指定hash值在對應table中的索引
 9     int i=indexFor(hash,table.length);
10     //若是i索引處的Entry不爲null,經過循環不斷遍歷e元素的下一個元素。
11     for(Entry<K,V> e=table[i];e!=null;e=e.next){
12         Object k;
13         if(e.hash==hash&&((k=e.key)==key||key.equals(k))){
14             V oldValue = e.value;
15             e.value = value;
16             e.recordAccess(this);
17             return oldValue;
18         }
19     }
20 // 若是i索引處的Entry爲null,代表此處尚未Entry。
21     modCount++;
22     // 將key、value添加到i索引處。
23     addEntry(hash, key, value, i);
24     return null;
25 }

從上面的源碼中能夠看出:當咱們往HashMap中put元素的時候,先根據key的hashCode從新計算hash值,根據hash值獲得這個元素在數組中的位置(即下標),若是數組該位置上已經存放了其餘元素了,那麼在這個位置上的元素將以鏈表的形式存放,新加入的放在鏈頭,最早加入的放在鏈尾。若是數組該位置上沒有元素,就直接將該元素放到此數組中的該位置上。指針

  2)讀取:code

public V get(Object key) {
    if (key == null)
        return getForNullKey();
    int hash = hash(key.hashCode());
    for (Entry<K,V> e = table[indexFor(hash, table.length)];
        e != null;
        e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
            return e.value;
    }
    return null;
}

有了上面存儲時的hash算法做爲基礎,理解起來這段代碼就很容易了。從上面的源代碼中能夠看出:從HashMap中get元素時,首先計算key的hashCode,找到數組中對應位置的某一元素,而後經過key的equals方法在對應位置的鏈表中找到須要的元素。對象

  以上內容摘抄自http://beyond99.blog.51cto.com/1469451/429789

    

HashMap使用了特殊的值,稱做散列碼,來取代對鍵的緩慢搜索。散列碼是「相對惟一」的、用以表明對象的int值,它是經過將該對象的某些信息進行轉換而生成的。hashCode()是根類Object中的方法,所以全部的Java對象都能產生散列碼。HashMap就是使用對象的hashCode()進行快速查詢的,此方法能顯著提升性能。

相關文章
相關標籤/搜索