Java集合學習-源碼US現金盤平臺出租實現細節-Set和Map
阿新 • • 發佈:2018-07-11
鍵值對 ces res 大小 調整 hashmap 次方 use int
set與mapUS現金盤平臺出租[ haozbbs.com ](http://haozbbs.com)Q1446595067 有非常大的關聯。簡單地說,把map的所有key拿出來就是一個set集合。map集合相當於一個存入了很多個key-value對象的set集合。相對應,set集合也可以如此擴展為map集合。
HashSet和HashMap都是利用Hash算法來決定(key的)存儲位置,而map集合的value是緊跟著key存儲的。
HashSet和HashMap對集合元素的存儲方式
HashMap源碼中的put方法
//threshold:鍵值對數量的極限值
//size:鍵值對的數量
/**
* Associates the specified value with the specified key in this map.
* If the map previously contained a mapping for the key, the old
* value is replaced.
* 將制定的值與此映射中的指定鍵關聯。如果已經存在以前的映射,則替換舊值
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with <tt>key</tt>, or
* <tt>null</tt> if there was no mapping for <tt>key</tt>.
* (A <tt>null</tt> return can also indicate that the map
* previously associated <tt>null</tt> with <tt>key</tt>.)
*/
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value);
//根據key計算hash值
int hash = hash(key);
//找到在table中對應的索引
int i = indexFor(hash, table.length);
//如果該索引位置的Entry不是null,就遍歷該索引位置的全部Entry
for (HashMap.Entry<K, V> e = table[i]; e != null; e = e.next) {
Object k;
//hashCode相同則說明儲存位置相同;
// 再通過equals比較,如果相同,則覆蓋原有value,並返回原有value。如果都不相同,則循環結束後執行addEntry方法
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
//如果索引i位置的Entry為null,調用addEntry方法
addEntry(hash, key, value, i);
return null;
}
//addEntry方法主要用來在需要的時候擴充table的大小,每次擴充一倍。然後調用了createEntry方法
/**
* Like addEntry except that this version is used when creating entries
* as part of Map construction or "pseudo-construction" (cloning,
* deserialization). This version needn‘t worry about resizing the table.
*
* Subclass overrides this to alter the behavior of HashMap(Map),
* clone, and readObject.
*/
void createEntry(int hash, K key, V value, int bucketIndex) {
//拿到制定索引處的Entry
HashMap.Entry<K,V> e = table[bucketIndex];
//在索引處放入新的Entry,並且新的Entry指向原來的Entry,沒有則指向null
table[bucketIndex] = new HashMap.Entry<>(hash, key, value, e);
//map中鍵值對的數量
size++;
}
/**
* The table, resized as necessary. Length MUST Always be a power of two.
*/
transient HashMap.Entry<K,V>[] table = (HashMap.Entry<K,V>[]) EMPTY_TABLE;
可以看到,table是一個數組,長度只能是2的n次方。在HashMap的一個構造方法中,系統會對構造時制定的容量大小做調整。所以創建HashMap時將初始容量設置為2的n次方,會減少系統計算開銷。
Java集合學習-源碼US現金盤平臺出租實現細節-Set和Map