jdk1.8相對於jdk1.6來說,區別在於1.8hashmap採用位桶+鍊錶+紅黑樹實現,
當鍊表的長度超過閾值(treeify_threshold = 8)的時候,會將鍊錶轉化為紅黑樹進行儲存。
1、hashmap的主要屬性
private
static
final
long serialversionuid = 362498820763181265l;
// 預設初始大小 aka 16
static
final
int default_initial_capacity = 1
<< 4;
//最大容量
static
final
int maximum_capacity = 1
<< 30;
//擴容比
static
final
float default_load_factor = 0.75f;
//紅黑樹閾值,當鍊表的大小大於此值是鍊錶自動轉為紅黑樹
static
final
int treeify_threshold = 8;
//紅黑樹閾值,當紅黑樹的大小小於此值是鍊錶自動轉為鍊錶
static
final
int untreeify_threshold = 6;
//樹的最小的容量,至少是 4 x treeify_threshold = 32 然後為了避免(resizing 和 treeification thresholds) 設定成64
static
final
int min_treeify_capacity = 64;
// 儲存元素的陣列,總是2的倍數
transient node table;
//快取的entryset()
transient set> entryset;
// 存放元素的個數,注意這個不等於陣列的長度。
transient
int size;
// 每次擴容和更改map結構的計數器
transient
int modcount;
// 臨界值 當實際大小(容量*填充因子)超過臨界值時,會進行擴容
int threshold;
// 填充因子
final
float loadfactor;
2、hashmap的建構函式
// 指定初始容量和填充因子的構造方法
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)
//初始化時可以傳入的引數可以是乙個map,會將map中的所有內容放入新的hashmap中
final
void putmapentries(map extends k, ? extends v> m, boolean evict)
else
if (s > threshold)
resize();
//將map中的所有內容放入新的hashmap中
for (map.entry extends k, ? extends v> e : m.entryset()) }}
3、主要的資料結構資料結構為鍊錶+紅黑樹
//node是單向鍊錶,它實現了map.entry介面
static
class
node
implements
map.entry
public
final k getkey()
public
final v getvalue()
public
final string tostring()
public
final
int hashcode()
public
final v setvalue(v newvalue)
public
final
boolean equals(object o)
return
false;}}
//static
final
class
treenode
extends
linkedhashmap.entry
final treenoderoot()
}...//此處方法過多,需要看的可以自己去檢視原始碼
}//儲存node的陣列
transient node table;
4、put和get方法hashmap不同於hashtable,可以key和value都可以為空
public v put(k key, v value)
//put
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;}}
v oldvalue = e.value;
if (!onlyifabsent || oldvalue == null)
e.value = value;
afternodeaccess(e);
return oldvalue;}}
++modcount;
if (++size > threshold)
resize();
afternodeinsertion(evict);
return
null;
}public v get(object key)
//get
final nodegetnode(int hash, object key) while ((e = e.next) != null);}}
return
null;
}
5、resize方法resize 其實是舊的node[ ]陣列複製到新擴容後的的node[ ]中
final node resize()
else
if ((newcap = oldcap << 1) < maximum_capacity &&
oldcap >= default_initial_capacity)
//擴2倍
newthr = oldthr << 1;
}else
if (oldthr > 0)
newcap = oldthr;
else
if (newthr == 0)
threshold = newthr;
@suppresswarnings()
node newtab = (node)new node[newcap];
table = newtab;
//陣列輔助到新的陣列中,分紅黑樹和鍊錶討論
if (oldtab != null)
else
} while ((e = next) != null);
if (lotail != null)
if (hitail != null) }}
}}return newtab;
}
6、其他一些方法
//計算hash值
static
final
int hash(object key)
//取消鍊錶轉為紅黑樹
final
void treeifybin(node tab, int hash)
tl = p;
} while ((e = e.next) != null);
if ((tab[index] = hd) != null)
hd.treeify(tab);}}
參考客 HashMap JDK1 7原始碼分析
hashmapjdk原始碼分析 建構函式 底層資料結構 基本屬性 擴容方式 預設值繼承關係 crud方式 基本屬性 static final int default initial capacity 1 4 aka 16 雜湊表中陣列預設初始值大小為16 static final int maxim...
ArrayList原始碼分析1 8
一 arraylist屬性 1 arraylist屬性主要就是當前陣列長度size,以及存放陣列的物件elementdata陣列 public class arraylistextends abstractlistimplements list,randomaccess,cloneable,seri...
ArrayList jdk1 8原始碼分析
arraylist是執行緒非安全的陣列列表,優勢在於陣列結構,查詢效率高,修改效率較低 由下圖的類圖,可以看出arraylist是可以序列化,複製的 1 自定義初始化容量大小,int型別,值為非負數 public arraylist int initialcapacity else if initi...