Map集合 原始碼分析

2021-10-02 02:33:36 字數 3344 閱讀 1746

map的實現類的結構

map:雙列資料,儲存key-value對的資料

hashmap:作為map的主要實現類;執行緒不安全的,效率高;可以儲存null和key的value

hashmap的底層

陣列+鍊錶 --> jdk7之前

陣列+鍊錶+紅黑樹 --> jdk8

linkedhashmap:保證在遍歷map元素時,可以按照新增的順序實現遍歷(原因:在原有的hashmap底層結構基礎上,新增了一對指標,指向前乙個和後乙個元素。對於頻繁的遍歷操作,此類執行效率高於hashmap)

treemap:保證按照新增的key-value對進行排序,實現排序遍歷。此時考慮key的自然排序或定製排序,底層使用紅黑樹

hashtable:作為古老的實現類:執行緒安全的,效率低不能儲存null的key和value

properties:常用來處理配置檔案。key和value都是string型別

map結構的理解:

map中的key:無序的,不可重複的,使用set儲存所有的key -->key所在的類要重寫equals和hashcode()(以hashmap為例)

map中的value:無序的,可重複的,使用collection儲存所有的value–>value所在的類要重寫equals()

乙個鍵值對:key-value構成了乙個entry物件

map中的entry:無序的,不可重複的,使用set儲存所有的entry

遍歷key-value的兩種方式

方式一:

set entryset = map.

entryset()

;iterator iterator1 = entryset.

iterator()

;while

(iterator1.

hasnext()

)

方式二:

set entryset = map.

entryset()

;iterator iterator1 = entryset.

iterator()

;while

(iterator1.

hasnext()

)

hashmap的底層實現原理?(jdk7為例)

hashmap map =

newhashmap();

在例項化以後,底層建立了長度是16的一維陣列entry[

] table

... 可能已經執行過多次put ...

map.

put(key1, value1)

;

首先,呼叫key1所在類的hashcode()計算key1雜湊值,此雜湊值經過某種演算法計算以後,得到在entry陣列中的存放位置。

如果此位置上的資料為空,此時的key1-value1新增成功。 -----> 情況1

如果此位置上的資料不為空,(意味著此位置上存在乙個或多個資料(以鍊錶形式存在)),比較key1和已經存在的乙個或多個資料的雜湊值:

如果key1的雜湊值與已經存在的資料的雜湊值都不相同,此時key1-value1新增成功。----> 情況2

如果key1的雜湊值和已經存在的某乙個資料(key2 -value2)的雜湊值相同,繼續比較:呼叫key1所在類的equals(key2):

如果equals()返回false:此時key1-value1新增成功 ----> 情況3

如果equals()返回true:使用value1替換value2

關於情況2和情況3:此時key1-value1和原來的資料以鍊錶的方式儲存

在不斷的新增過程中,會涉及到擴容問題,當超出臨界值(且要存放的位置非空)時,擴容。預設的擴容方式:擴容為原來容量的2倍,並將原有的陣列複製過來

jdk8相較於jdk7在底層實現方面的不同:

1,newhashmap():底層沒有建立乙個長度為16的陣列

2,jdk8底層的陣列是:node,而非entry

3,首次呼叫put()方法時,底層建立長度為16的陣列

4,jdk7底層結構只有:陣列+鍊錶。jdk8中底層結構:陣列+鍊錶+紅黑樹

當陣列的某乙個索引位置上的元素以鍊錶形式存在的資料個數》8 且當前陣列的長度 > 64時,此時此索引位置上的所有資料改為紅黑樹儲存

default_initial_capacity:hashmap的預設容量為16

default_load_factor:hashmap的預設載入因子:0.75

threshold:擴容的臨界值,=容量 * 填充因子:16 * 0.75 -->12

treify_threshold:bucket中煉表長度大於該預設值,轉化為紅黑樹:jdk8

min_treeify_capacity桶中的node被樹化時最小的hash表容量:64

linkedhashmap的底層實現原理

原始碼

static class entryextends hashmap.node

}

繼承hashmap,使用的鍵值對節點是entity 他繼承了hashmap 的node,並新增了兩個引用,分別是 before 和 after。用於維護雙向鍊錶

treemap:

向treemap中新增key-value,要求必須是由同乙個類建立的物件

因為要按照key進行排序:自然排序,定製排序(不可用value進行排序!)

自然排序:實現comparable介面,重寫compareto方法

定製排序:new comparator()內部類

properties:常用來處理配置檔案,key和value都是string型別

properties pros =

newproperties()

;fileinputstream fis =

newfileinputstream

("jdbc.properties");

pros.

load

(fis)

;//載入流對應的檔案

pros.

getproperty

("檔案中對應的值"

);

map運算元原始碼分析

val rdd1 sc.parallelize list 1 2,3 4,5 rdd1.map a a 2 collect foreach println def map u classtag f t u rdd u withscopeprivate spark def clean f anyref...

原始碼分析集合Hashmap

public v put k key,v value final v putval int hash,k key,v value,boolean onlyifabsent,boolean evict 如果鍊錶中有相同的key直接跳出迴圈 if e.hash hash k e.key key key ...

Java集合之 Map原始碼解析

hashmap 也是我們平時開發中使用頻率很高的雙列集合,直接父類是abstractmap,是基於hash表儲存的一種集合。幾個重要的類變數 hash表的初始化大小,預設為16.是基於陣列實現的。static final int default initial capacity 1 4 aka 16...