java.util.HashMap源碼初探

來源:互聯網
上載者:User

對於一個儲存類的分析,無非從兩點入手:儲存用的資料結構,儲存的運行機制。

資料結構:

數組

 

    /**     * The table, resized as necessary. Length MUST Always be a power of two.     */    transient Entry[] table;

Entry

 

鏈表格式。

也即,HashMap中採用的是“連結法”來處理碰撞問題的。


運行機制:

put、get

put方法

 

    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;    }

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;    }

可以看出,重要的一句代碼為:

 

 

if (e.hash == hash && ((k = e.key) == key || key.equals(k)))

 


這句代碼的作用是判斷兩個Key對象是否“相同”,這裡的相同的意思是指兩個Key完全可以不分彼此,可以作為同一個Key使用。

在put方法中,如果兩個Key的hashCode相同,且equals符合,這裡是把原有的的value替換成新的value。


測試代碼:

 

package test.junit;import java.util.HashMap;import junit.framework.TestCase;/** * HashMap中判斷兩個Key是否相同:先判斷hashCode,在判斷是否equals * e.hash == hash && ((k = e.key) == key || key.equals(k)) * @author xuefeng * */public class HashMapTest extends TestCase {/** * v1和v4的hashCode相同,但是equals不符合,所以v1和v4會組成一個鏈表。 */public void testKey1() {HashMap<Key, Value> map = new HashMap<Key, Value>();Key k1 = new Key(1);Key k4 = new Key(4);Value v1 = new Value(1);Value v4 = new Value(4);map.put(k1, v1);map.put(k4, v4);assertEquals(v1, map.get(k1));assertEquals(v4, map.get(k4));}/** * v1和v4的hashCode相同,而且equals也符合,所以v1會被v4替換掉,k1和k4指向同一個v4。 */public void testKey2() {HashMap<Key2, Value> map = new HashMap<Key2, Value>();Key2 k1 = new Key2(1);Key2 k4 = new Key2(4);Value v1 = new Value(1);Value v4 = new Value(4);map.put(k1, v1);map.put(k4, v4); // 這裡會替換掉v1//assertEquals(v1, map.get(k1));assertEquals(v4, map.get(k1));assertEquals(v4, map.get(k4));}}class Key {public int m;public Key(int m) {this.m = m;}@Overridepublic int hashCode() {return m%3;}}class Value {public int m;public Value(int m) {this.m = m;}}class Key2 {public int m;public Key2(int m) {this.m = m;}@Overridepublic int hashCode() {return m%3;}@Overridepublic boolean equals(Object obj) {if(obj == null || !(obj instanceof Key2)) return false;Key2 other = (Key2)obj;return this.hashCode() == other.hashCode();}}

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.