昨天有朋友問(wèn)我领突,IDEA調(diào)式HashMap,在調(diào)式下面代碼的時(shí)候解虱,entrySet一開始就有值了攘须,但是沒(méi)有找到給entrySet賦值的地方。
public Set<Map.Entry<K,V>> entrySet() {
Set<Map.Entry<K,V>> es;
return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
}
我寫了段代碼驗(yàn)證殴泰,發(fā)現(xiàn)確實(shí)如此于宙,開始我以為是jdk1.8的原因,相同代碼放到1.6后還是如此悍汛。
public class HashMapEntrySetTest {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("aaa","aaaa");
map.entrySet();
}
}
調(diào)式結(jié)果:
我在https://blog.csdn.net/lwj_zeal/article/details/72899934找到了答案捞魁,IDEA在調(diào)式的時(shí)候會(huì)調(diào)用對(duì)象的toString方法。驗(yàn)證代碼如下:
public class DebugTest {
@Override
public String toString() {
System.out.println("======debug======");
return super.toString();
}
public static void main(String[] args) {
System.out.println("======start======");
DebugTest debugTest = new DebugTest();
}
}
不加debug輸出結(jié)果是:======start======
在System.out.println("======start======");行加斷點(diǎn)离咐,單步執(zhí)行時(shí)會(huì)多輸出======debug======谱俭。也就是說(shuō)IDEA在單步執(zhí)行時(shí)會(huì)調(diào)用對(duì)象的toString方法。
現(xiàn)在再來(lái)看HashMap的toString方法宵蛀,HashMap沒(méi)有重寫toString昆著,而是在它的父類AbstractMap重寫了。
public String toString() {
Iterator<Entry<K,V>> i = entrySet().iterator();
if (! i.hasNext())
return "{}";
StringBuilder sb = new StringBuilder();
sb.append('{');
for (;;) {
Entry<K,V> e = i.next();
K key = e.getKey();
V value = e.getValue();
sb.append(key == this ? "(this Map)" : key);
sb.append('=');
sb.append(value == this ? "(this Map)" : value);
if (! i.hasNext())
return sb.append('}').toString();
sb.append(',').append(' ');
}
}
從上面代碼可以看到术陶,在toString中有調(diào)用entrySet()方法凑懂,entrySet第一次賦值是在這里。
為了再次確認(rèn)是IDEA的問(wèn)題梧宫,我又在eclipse中調(diào)式entrySet方法接谨,發(fā)現(xiàn)第一次進(jìn)去的時(shí)候是為空。