這一篇主要看一下遍歷相關的原始碼。
@override
public
boolean
containskey(object key)
int hash = collections.secondaryhash(key);
hashmapentry tab = table;
for (hashmapentrye = tab[hash & (tab.length - 1)];
e != null; e = e.next)
}return
false;
}
橫向遍歷陣列,縱向遍歷鍊錶,如果沒有找到別忘了hashmap還維護了乙個entryfornullkey。
但是區分了value為null的條件,因為null.equals會報錯。
@override public boolean containsvalue(object value) }}
return entryfornullkey != null && entryfornullkey.value == null;
}// value is non-null
for (int i = 0; i < len; i++) }}
return entryfornullkey != null && value.equals(entryfornullkey.value);
}
由於keyset、values、entryset的實現邏輯一樣,此處就只看keyset的原始碼
@override
public setkeyset()
可以看到返回了乙個keyset物件
private
final
class
keyset
extends
abstractset
public
int size()
public
boolean isempty()
public
boolean contains(object o)
public
boolean remove(object o)
public
void clear()
}
裡面包含了常用的方法,size方法直接用hashmap物件的size,isempty一樣,contains則是使用hashmap的containskey方法,remove也是呼叫hashmap物件的方法,關鍵的是iterator這個迭代器。
iteratornewkeyiterator()
原始碼很簡單,直接返回keyiterator物件,繼續向下走。
private
final
class
keyiterator
extends
ha****erator
implements
iterator
}
返回了nextentry.key,看名字應該是下一項,但nextentry**來的呢?
看keyiterator 的繼承,ha****erator它是整個hashmap迭代的實現者
private
abstract
class ha****erator
nextentry = next;}}
public boolean hasnext()
hashmapentrynextentry()
nextentry = next;
return lastentryreturned = entrytoreturn;
}public
void
remove()
}
至此hashmap的原始碼就看完了,至於其他功能類的方法,相信有了這兩篇的基礎想看懂原理應該不難。
hashset的內部實現其實也是hashmap,只是hashset存入的value作為key,hashset物件作為value存入hashmap。
HashMap原始碼分析 下
本節將分析hashmap的增刪改查 首先來說hashmap的插入流程 1.計算下標 2.何時擴容 3.何時鍊錶轉紅黑樹,具體如下 1 首先進行雜湊值的擾動,獲取新的hash值,key null 0 h key.hashcode h 16 2 判斷tab是否為空或者長度為0,如果是則進行擴容操作。if...
簡單擼下Hashmap原始碼
陣列 其實所謂的陣列指的就是一組相關型別的變數集合,並且這些變數彼此之間沒有任何的關聯。儲存區間連續,占用記憶體嚴重,陣列有下標,查詢資料快,但是增刪比較慢 鍊錶 一種常見的基礎資料結構,是一種線性表,但是不會按照線性的順序儲存資料,而是每乙個節點裡存到下乙個節點的指標。儲存區間離散,占用記憶體比較...
HashMap原始碼系列 HashMap的屬性
public class hashmap extends abstractmap implements map,cloneable,serializable容載因子 容載因子越大,table陣列中儲存的資料越密集,碰撞的可能性就越大。容載因子越小,儲存越稀疏,碰撞的可能性就越小,不過浪費儲存空間。轉...