Java原始碼分析之HashMap

2021-07-28 05:59:15 字數 4299 閱讀 2171

//預設的初始容量,空間必須為2的冪

static

final

int default_initial_capacity = 1

<< 4; // aka 16

//最大容量

static

final

int maximum_capacity = 1

<< 30;

//預設的載入因子,這裡解釋一下載入因子,在map被建立後,就有了乙個容量,在put鍵值對時,會首先算key的hashcode,然後根據hash值來裝進「桶」,載入因子的取值範圍是(0,1],載入因子乘初始容量,就是能裝的最大值,舉個例子,加入初始容量是16,初始載入因子是0.75,0.75*16=12,現在如果16個桶中已經裝了12個,當再來乙個,並且該對應的值還沒有被裝進通,那麼容量就會擴大,變成原來的2倍,載入因子有什麼用呢,就是平衡時間和空間,假如值太小了,那麼在沒有裝幾個的時候,就會擴容,對空間要求比較高,當值太大的時候,衝突會增加的比較多,所以裝的也就更多,對時間要求比較高,所以折中是比較好的選擇

static

final

float default_load_factor = 0.75f;

int threshold;

final

float loadfactor;

public

hashmap(int initialcapacity, float loadfactor)

//返回2的冪

static

final

int tablesizefor(int cap)

public

hashmap(int initialcapacity)

public

hashmap()

public

hashmap(map<? extends k, ? extends v> m)

//通過這個類,來儲存鍵值對

static class nodeimplements map.entry

public final k getkey()

public final v getvalue()

public final string tostring()

//鍵值對的hash值是將key,value的hash值異或起來

public final int

hashcode()

public final v setvalue(v newvalue)

public final boolean equals(object o)

return

false;

}}

put方法
public v put(k key, v value) 

//onlyifabsent如果為真時,如果原map中已經存在了key值的對,那麼不改變原來的對

final v putval(int hash, k key, v value, boolean onlyifabsent,

boolean evict)

if (e.hash == hash &&

((k = e.key) == key || (key != null && key.equals(k))))

break;

p = e;}}

//當已經存在key時

v oldvalue = e.value;

//如果oldvalue為空,或者onlyifabsent 為false,則覆蓋

if (!onlyifabsent || oldvalue == null)

e.value = value;

afternodeaccess(e);

return oldvalue;}}

++modcount;

//是否需要擴容

if (++size > threshold)

resize();

afternodeinsertion(evict);

return

null;

}

final void putmapentries(map<? extends k, ? extends v> m, boolean evict) 

else

if (s > threshold)

resize();

//全部put進去,這也給我們了乙個遍歷map的模板

for (map.entry<? extends k, ? extends v> e : m.entryset())

}}

public

void

putall(map<? extends k, ? extends v> m)

get方法

public v get(object key) 

final nodegetnode(int hash, object key) while ((e = e.next) != null);}}

return

null;

}

//是否包含key

public

boolean

containskey(object key)

//查詢是否存在value,從全部中找 o(n)

public boolean containsvalue(object value) }}

return

false;

}

remove方法
public v remove(object key) 

//移除key和value都相等的數,注意,倒數第二個引數是true

public boolean remove(object key, object value)

//matchvalue表示刪除時候,是否需要value也相等,movable表示是否可以移動

final noderemovenode(int hash, object key, object value,

boolean matchvalue, boolean movable)

p = e;

} while ((e = e.next) != null);}}

//找到了,並且看是否需要value也相等,並判斷value是否相等

if (node != null && (!matchvalue || (v = node.value) == value ||

(value != null && value.equals(v))))

}return

null;

}

size() 與 isempty()
public

intsize()

public

boolean

isempty()

clear()
public

void

clear()

}

keyset()
//keyset是繼承自abstractset

public setkeyset()

return ks;

}

//居然叫values,不叫valuesset,神奇

public collectionvalues()

return vs;

}

//entryset,可以用來遍歷

public

set<

map.entry> entryset()

replace方法
//先取到node,再改變,返回舊的值

public v replace(k key, v value)

return

null;

}

//有舊值的替換

public boolean replace(k key, v oldvalue, v newvalue)

return

false;

}

是為了檢測多執行緒中,是否被其他執行緒修改,雖然如此,但依舊不是執行緒安全的

除了這些,還有迭代器這些,先不說了,另外,裡面有紅黑樹的實現,可以改日好好研究一下

Java原始碼分析之ArrayList

自我學習原始碼,也借鑑了網上其他的資料,有寫的不準確的地方,請輕噴,謝謝 1 繼承自abstractlist類 2 實現了randomaccess介面,randomaccess介面是list 實現所使用的標記介面,用來表明其支援快速 通常是固 定時間 隨機訪問。此介面的主要目的是允許一般的演算法更改...

JAVA原始碼分析Collection之Map

map的底層實現 linkedlist陣列,乙個非常大的陣列,linkedlist中儲存的是myentry物件 包括key和value屬性的物件 因為要保證map中的查詢速度比較快,是基於雜湊演算法來實現的,雜湊的主要實現是依靠hashcode方法。hashcode的產生是基於,記憶體位址產生的,保...

Java原始碼分析之ArrayList

儲存arraylist中的內容 transient object elementdata non private to simplify nested class access 表示元素的數量 private int size transient 關鍵字,就是這部分不參與序列化 建構函式有三個 沒有...