HashMap是Java中的一個重要的數據結構!html
與HashMap更重要的一個數據結構是HashTable,其中最重要的區別是HashTable傳說中是線程安全的(之因此說他是傳說是由於我並無去理解爲何,這是個人錯,沒有理解就搬上了講臺!)java
HashMap的內部結構很簡單,以下(圖片來自importnews,專屬java的一個實時blog.本文也必定程度上參考了importnews,之全部沒有直接轉載是由於我以爲,有些東西,你只是看到了,他並不屬於你!而我要作的,就是消化它,達到能夠有本身看法的地方,原文連接地址:http://www.importnew.com/10620.html)數組
在HashMap內部,實現存貯key-value鍵值對的是一個Entity的內部類,安全
static class Entry implements Map.Entry { final K key; V value; Entry next; final int hash; ...//More code goes here } `
這個類能夠構成一個鏈表,在key中的hashCode相同時,會構成一個鏈表,數據結構
這個類在HashMap中構成了一個table數組,全部的鍵值對就保留在這個鍵值對數組之中,這個數據默認的長度是16,當數據超過這個大小以後,會自動的真正增加,可是若是數據剛恰好處於增加的上邊緣,也就是>=,會形成數據內存大浪費,一些文章推薦咱們在使用一些集合類的時候要指定好它的大小,避免形成過大的內存泄漏函數
從咱們日常使用的HashMap中咱們能夠得出,操縱HashMap只是經過put和get方法post
1.瞭解put方法this
public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key.hashCode()); int i = indexFor(hash, table.length); for (Entry<k , V> e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }
對key作null檢查。若是key是null,會被存儲到table[0],由於null的hash值老是0。spa
key的hashcode()方法會被調用,而後計算hash值。hash值用來找到存儲Entry對象的數組的索引。有時候hash函數可能寫的 很很差,因此JDK的設計者添加了另外一個叫作hash()的方法,它接收剛纔計算的hash值做爲參數。若是你想了解更多關於hash()函數的東西,可 以參考:hashmap中的hash和indexFor方法線程
indexFor(hash,table.length)用來計算在table數組中存儲Entry對象的精確的索引。
在咱們的例子中已經看到,若是兩個key(這裏指的是兩個不一樣key值)有相同的hash值(也叫衝突),他們會以鏈表的形式來存儲。因此,這裏咱們就迭代鏈表。
2.瞭解get
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; }
你傳遞一個key從hashmap總獲取value的時候:
對key進行null檢查。若是key是null,table[0]這個位置的元素將被返回。
key的hashcode()方法被調用,而後計算hash值。
indexFor(hash,table.length)用來計算要獲取的Entry對象在table數組中的精確的位置,使用剛纔計算的hash值。
在獲取了table數組的索引以後,會迭代鏈表,調用equals()方法檢查key的相等性,若是equals()方法返回true,get方法返回Entry對象的value,不然,返回null。
總結: