美文网首页
HashMap中entrySet调式

HashMap中entrySet调式

作者: xiaoming_he | 来源:发表于2018-08-05 11:37 被阅读0次

昨天有朋友问我,IDEA调式HashMap,在调式下面代码的时候,entrySet一开始就有值了,但是没有找到给entrySet赋值的地方。

public Set<Map.Entry<K,V>> entrySet() {
    Set<Map.Entry<K,V>> es;
    return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
}

我写了段代码验证,发现确实如此,开始我以为是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();
    }
}

调式结果:

IDEA调式
我在https://blog.csdn.net/lwj_zeal/article/details/72899934找到了答案,IDEA在调式的时候会调用对象的toString方法。验证代码如下:
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输出结果是:======start======
在System.out.println("======start======");行加断点,单步执行时会多输出======debug======。也就是说IDEA在单步执行时会调用对象的toString方法。
现在再来看HashMap的toString方法,HashMap没有重写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中有调用entrySet()方法,entrySet第一次赋值是在这里。
为了再次确认是IDEA的问题,我又在eclipse中调式entrySet方法,发现第一次进去的时候是为空。


eclipse调式

相关文章

网友评论

      本文标题:HashMap中entrySet调式

      本文链接:https://www.haomeiwen.com/subject/zjcbvftx.html