我發現一個很神奇的東西,簡單的代碼如下:HashMap中如何和何時初始化的entrySet和增加價值到它
public class Demo{
public static void main(String[] args){
HashMap<String,String> map = new HashMap<String,String>();
map.put("a", "aa");
System.out.println("end");
}
}
調用後
HashMap<String,String> map = new HashMap<String,String>();
字段變量的entrySet不是null,也就是說它已被初始化。
然後這是我第一次問題,當的entrySet已初始化? 它似乎相關的代碼應該是HashMap中的結構,但低於是它似乎這個構造
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
的源代碼中有不存在其初始化的entrySet代碼。
事情繼續下去。 後調用
map.put("a","aa")
場變量表和的entrySet的如下拍攝的內容。 然後,這是我的第二個問題:何時將此值添加到entrySet? 看來應該是把方法實現了這些東西。 以下是把方法。
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
它調用putVal方法和下面是一些代碼putVal
final V putVal(...) {
....
tab[i] = newNode(hash, key, value, null);
....
++modCount;//after invoke this the entrySet is still empty
if (++size > threshold)
resize();//this has not been executed
afterNodeInsertion(evict);//I debug several times, sometimes before invoke this the entrySet has an Element and sometimes
return null;
}
調用後
++modCount;
的的entrySet是空 和之前調用
afterNodeInsertion(evict);
entrySet有一個元素。 但它似乎這兩行之間的代碼與entrySet沒有任何關係。 我想也許存在多個線程運行的entrySet然後我寫與jvm_ti一個小工具,打印的調用下面包類java.util中,發現只有一個線程的線程ID。
那我想念什麼?調試過程中是否存在問題?希望我已經清楚地描述了我的問題,並且一切都會很感激。
地址:我的Java版本是1.8.0_77和Eclipse版本是4.6.1 和 4.5.1
爲什麼這很重要?它如何影響合同? –
@SkinnyJ它沒有關係,但我想知道實際的細節並遇到一些問題。 –
你可以添加一個斷點到HashMap中的方法entrySet()嗎?我假設輸入集在那裏被初始化。如果您在那裏放置斷點並且線程暫停,您可以看到調用此方法的代碼的堆棧跟蹤。 – toongeorges