HashMap,ConcurrentHashMap,Hashtable,HashSetTreeMap

【一、HashMap的工做原理?】

答:
A、HashMap基於Hashing原理,經過put()和get()方法存儲與獲取對象。
B、咱們將值傳遞給put()方法,它調用鍵對象的hashCode()方法來計算hashcode,而後找到bucket位置來存儲對象。
C、獲取對象時,經過鍵對象的equals()方法找到正確的鍵值對,而後返回值對象。
D、HashMap使用鏈表來解決碰撞問題,當發生碰撞了,對象將會儲存存在鏈表的下一個節點。
E、HashMap在每一個鏈表節點中存儲鍵值對對象。算法

【二、什麼是Hashing原理?】

散列法(Hashing)是一種將字符組成的字符換轉換爲固定長度的數值或索引的方法,稱爲散列法,也叫哈希法。
因爲經過更短的哈希值比用原來的值進行數據庫搜索更快,這種方法通常用在數據庫中創建索引進行搜索,同時還用在各類解密算法中。數據庫

【三、HashMap中的bucket位置是什麼?】

答:HashMap及其子類,採用Hash算法來決定集合中元素的存儲位置。當系統開始初始化HashMap時,系統會建立一個長度爲capacity的Entry數組。
這個數組裏能夠存儲元素的位置被稱爲bucket(桶)。每一個bucket都有指定索引,系統能夠根據其索引快速訪問該bucket裏存儲的元素。
HashMap的每一個bucket(桶)只存儲一個元素Entry,因爲Entry對象能夠包含一個引用變量,也就是Entry指向另外一個Entry依次類推,就造成了一個鏈。
HashMap,ConcurrentHashMap,Hashtable,HashSetTreeMap數組

【四、HashMap的讀取實現?】

答:當HashMap的每一個bucket裏面只存儲一個Entry,也就是沒有經過指針產生Entry鏈時,此時HashMap具備最好的性能。
當程序取出對應的value時,系統只要先計算出key的hashcode返回值,根據hashode返回值找到該key在table數組中的索引,而後取出索引處的Entry,返回給能夠對應的value便可。安全

public V get(Object key) {   
 // 若是 key 是 null,調用 getForNullKey 取出對應的 value   
 if (key == null)   
         return getForNullKey();   
 // 根據該 key 的 hashCode 值計算它的 hash 碼  
 int hash = hash(key.hashCode());   
 // 直接取出 table 數組中指定索引處的值,  
 for (Entry<K,V> e = table[indexFor(hash, table.length)]; e != null; e = e.next){   
         Object k;   
         // 若是該 Entry 的 key 與被搜索 key 相同  
         if (e.hash == hash && ((k = e.key) == key   
                 || key.equals(k)))   
                 return e.value;   
 }   
 return null;   
}

若是HashMap的每一個桶裏只有一個Entry時,HashMap能夠根據索引快速的取出桶裏的Entry。
在碰撞問題下,單個桶裏存儲的不是一個Entry,而是一個Entry鏈,系統只有按順序遍歷每一個Entry,知道找到目標Entry爲止。
HashMap在底層將key-value做爲一個總體,進行處理。這個總體就是Entry對象。HashMap底層採用一個Entry[]數組來保存全部的key-value。
當須要存儲一個Entry對象時,會根據Hash算法來決定其存儲位置;
先判斷該位置上有沒有Entry,沒有的話就建立一個Entry對象,再在這個位置上插入;
若是有Entry的話,經過鏈表的遍歷方式去逐個遍歷,經過Equals方法將key和已有的key進行比較,看看有沒有已經存在的key,有的話用新的value替換以前的value;若是沒有則在table[i]插入該Entry,把原來的table[i]位置上的Entry賦值給新的Entry的next。因此新的Entry插入的位置永遠是鏈表的最前面。
當須要取出一個Entry對象時,會根據Hash算法找到其存儲位置,直接取出Entry。數據結構

【五、當兩個不一樣的鍵對象的hashcode相同會怎樣?】

答:會儲存在同一個bucket位置的鏈表中。鍵對象的equals()方法用來找到鍵值對。ide

【六、什麼是HashTable?】

答:哈希表(HashTable)又叫作散列表,是根據關鍵碼值(即鍵值對)而直接訪問的數據結構。也就是說,它經過把關鍵碼映射到表中一個位置來訪問記錄,以加快查找速度性能

【七、HashMap和Hashtable的區別?】

答:一、繼承的父類不一樣
Hashtable繼承自Dictionary類,而HashMap繼承自AbstractMap類。但兩者都實現了Map接口。
二、線程安全性不一樣
hashmap:此實現不是同步的。若是多個線程同時訪問一個哈希映射,而其中至少一個線程從結構上修改了該映射,則它必須保持外部同步。
HashMap和Hashtable都實現了Map接口,但決定用哪個以前先要弄清楚它們之間的分別。主要的區別有:線程安全性,同步(synchronization),以及速度。
HashMap幾乎能夠等價於Hashtable,除了HashMap是非synchronized的,並能夠接受null(HashMap能夠接受爲null的鍵值(key)和值(value),而Hashtable則不行)。
HashMap是非synchronized,而Hashtable是synchronized,這意味着Hashtable是線程安全的,多個線程能夠共享一個Hashtable;而若是沒有正確的同步的話,多個線程是不能共享HashMap的。
HashMap不能保證隨着時間的推移Map中的元素次序是不變的。
三、key和value是否容許null值
Hashtable中,key和value都不容許出現null值。
可是若是在Hashtable中有相似put(null,null)的操做,編譯一樣能夠經過,由於key和value都是Object類型,但運行時會拋出NullPointerException異常,這是JDK的規範規定的。
HashMap中,null能夠做爲鍵,這樣的鍵只有一個;能夠有一個或多個鍵所對應的值爲null。
當get()方法返回null值時,多是 HashMap中沒有該鍵,也可能使該鍵所對應的值爲null。所以,在HashMap中不能由get()方法來判斷HashMap中是否存在某個鍵, 而應該用containsKey()方法來判斷。線程

【八、什麼是HashSet?】

HashSet實現了Set接口,它不容許集合中有重複的值,當咱們提到HashSet時,第一件事情就是在將對象存儲在HashSet以前,要先確保對象重寫equals()和hashCode()方法,這樣才能比較對象的值是否相等,以確保set中沒有儲存相等的對象。若是咱們沒有重寫這兩個方法,將會使用這個方法的默認實現。public boolean add(Object o)方法用來在Set中添加元素,當元素值重複時則會當即返回false,若是成功添加的話會返回true。
HashMap,ConcurrentHashMap,Hashtable,HashSetTreeMap指針

相關文章
相關標籤/搜索