一、初始化
1.無參建構函式
//負載因子預設值
static final float default_load_factor = 0.75f;
//指定loadfactor負載因子的值是0.75f
public hashmap()
2.指定初始化大小和負載因子
//hashmap的最大容量
static final int maximum_capacity = 1 << 30; //1左移30位等於1073741824
//initialcapacity:傳入的hashmap初始化大小
//loadfactor:負載因子,此時是預設值0.75f
public hashmap(int initialcapacity, float loadfactor)
//返回乙個大於等於initialcapacity的2的n次方最近的乙個值
//假設傳入的initialcapacity=5
static final int tablesizefor(int cap)
3.指定初始化大小(會呼叫2)
//initialcapacity:hashmap初始化大小
public hashmap(int initialcapacity)
二、put元素(轉紅黑樹和put乙個treenode時待補充)
//插入元素
public v put(k key, v value)
//計算hash值
static final int hash(object key)
//hashmap的陣列
transient node table;
//存放資料
final v putval(int hash, k key, v value, boolean onlyifabsent,
boolean evict)
//新增的資料與如果下乙個值的hash值和key相同,直接跳出
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
//下乙個位置的資料賦值給p,迴圈繼續
p = e;}}
//key存在,更新新值,返回舊值
v oldvalue = e.value;
if (!onlyifabsent || oldvalue == null)
e.value = value;
afternodeaccess(e);
return oldvalue;}}
++modcount;
//判斷是否超過需要的大小
if (++size > threshold)
resize();
afternodeinsertion(evict);
return null;
}//初始化或擴容時呼叫
final node resize()
//新的容量是舊陣列的容量左移以為即:oldcap*2。如果陣列容量大於default_initial_capacity=16時,擴容的容量也要×2
else if ((newcap = oldcap << 1) < maximum_capacity &&
oldcap >= default_initial_capacity)
newthr = oldthr << 1; // double threshold
}//舊陣列為空,進行初始化
else if (oldthr > 0) // 初始化容量設定為threshold(需要擴容的值)
newcap = oldthr;
else
//新的threshold(需要擴容的大小)為零時,newthr=newcap * loadfactor
if (newthr == 0)
//賦值回threshold
threshold = newthr;
@suppresswarnings()
//定義乙個新hashmap的陣列,值是新的容量
node newtab = (node)new node[newcap];
table = newtab;
//舊陣列不為空,擴容
if (oldtab != null)
else
} while ((e = next) != null);
//將當前陣列位置下的鍊錶(hihead/lohead)放到新陣列的(當前陣列位置+oldcap)位置
//lotail/hitail.next設定為空為了防止lotail和lohead(或hihead和hitail)指向同乙個位址時資料重複,
//重複時則清除lohead和hihead的next值
if (lotail != null)
if (hitail != null) }}
}}
return newtab;
}
三、get元素
//返回鍵對應的值
public v get(object key)
//計算hash值
static final int hash(object key)
//根據key獲得對應的node
final nodegetnode(int hash, object key) while ((e = e.next) != null);}}
return null;
}
四、remove元素
//返回鍵對應的值
public v remove(object key)
//計算hash值
static final int hash(object key)
//value:如果是matchvalue則需要傳入
//matchvalue:如果等於true則還需要匹配值也相等
//movable:如果為false則在刪除時不要移動其他節點
final noderemovenode(int hash, object key, object value,boolean matchvalue, boolean movable)
p = e;
} while ((e = e.next) != null);}}
//找到元素,並且matchvalue=false或者找到的node的value與指定value相等
if (node != null && (!matchvalue || (v = node.value) == value || (value != null && value.equals(v))))
}return null;
}
HashMap1 8原始碼分析
1 hashmap的原理,內部資料結構如何?底層使用雜湊表 陣列 鍊錶 當鍊表過長 其實是大於8 的時候會將鍊錶轉換成紅黑樹,以實現n log n 的查詢。2 具體過程 對 key 求 hash 值,然後再計算 下標。如果沒有碰撞,直接放入桶中,如果碰撞了,以鍊錶的方式鏈結到後面,如果鍊錶長度超過閥...
原始碼分析 HashMap 1 8
1.0 資料結構 2.0 儲存流程 3.0 陣列元素 鍊錶節點的實現類 hashmap中的陣列元素 鍊錶節點 採用node類 實現,與jdk1.7相比只是把entry換了個名字 hashmap中的紅黑樹節點 採用treenode類 實現 紅黑樹節點 實現類 繼承自linkedhashmap.entr...
JDK原始碼分析系列 HashMap 1 8
預設的初始化容量,必須是2的n次冪 static final int default initial capacity 1 4 aka 16 最大的容量是2的30次冪 static final int maximum capacity 1 30 預設的負載因子 static final float ...