1. 程式人生 > >Java集合學習-源碼US現金盤平臺出租實現細節-Set和Map

Java集合學習-源碼US現金盤平臺出租實現細節-Set和Map

鍵值對 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