JDK8:HashMap源碼解析:newNode方法、Node類

一、概述

在Map中存儲的每一個鍵值對都是以一個Map.Entry<K,V>的實現對象存儲的,Map.Entry是一個接口,不能實例化,所以Map的不同實現類,存儲鍵值對的方式也會有所不同,只要這個鍵值對的類實現了Map.Entry接口即可。

在HashMap中鍵值對的存儲方式有兩種:

其中一種是我們比較熟知的鏈表存儲結構,也就是以HashMap.Node<K,V>類的對象方式存儲的, Node類是HashMap的一個靜態內部類,實現了 Map.Entry<K,V>接口。在調用put方法創建一個新的鍵值對時,會調用newNode方法來創建Node對象。

 

二、方法解析

// 該方法很簡單,只是調用了Node類的構造函數
Node<K,V> newNode(int hash, K key, V value, Node<K,V> next) {
        return new Node<>(hash, key, value, next);
}

 

我們接下來看下Node類的代碼

 

/**
* 該類只實現了 Map.Entry 接口,
* 所以該類只需要實現getKey、getValue、setValue三個方法即可
* 除此之外以什麼樣的方式來組織數據,就和接口無關了
*/
static class Node<K,V> implements Map.Entry<K,V> {
        final int hash; // hash值,不可變
        final K key; // 鍵,不可變
        V value; // 值
        Node<K,V> next; // 下一個節點

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        // 實現接口定義的方法,且該方法不可被重寫
        public final K getKey()        { return key; }
        // 實現接口定義的方法,且該方法不可被重寫
        public final V getValue()      { return value; }
        public final String toString() { return key + "=" + value; }

        // 重寫父類Object的hashCode方法,且該方法不可被自己的子類再重寫
        // 返回:key的hashCode值和value的hashCode值進行異或運算結果
        public final int hashCode() {
            return Objects.hashCode(key) ^ Objects.hashCode(value);
        }

        // 實現接口定義的方法,且該方法不可被重寫
        // 設值,返回舊值
        public final V setValue(V newValue) {
            V oldValue = value;
            value = newValue;
            return oldValue;
        }

        /*
         * 重寫父類Object的equals方法,且該方法不可被自己的子類再重寫
         * 判斷相等的依據是,只要是Map.Entry的一個實例,並且鍵鍵、值值都相等就返回True
         */
        public final boolean equals(Object o) {
            if (o == this)
                return true;
            if (o instanceof Map.Entry) {
                Map.Entry<?,?> e = (Map.Entry<?,?>)o;
                if (Objects.equals(key, e.getKey()) &&
                    Objects.equals(value, e.getValue()))
                    return true;
            }
            return false;
        }
}

 

三、小貼士

在上一個小節中存在着Objects.equals、Objects.hashCode這種靜態方法,其內部實現都特別簡單。

以下是截取Objects類中這兩個方法的實現。

public static int hashCode(Object o) {
        return o != null ? o.hashCode() : 0;
}

public static boolean equals(Object a, Object b) {
        return (a == b) || (a != null && a.equals(b));
}

最主要的幫助用戶節省了空值判斷指針相同判斷。

 

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