发现很多讲entrySet原理的文章都讲到entrySet方法返回map包含的映射集合视图就没了,并没有讲到为什么entrySet没有赋值却可以取到数据,这里简单梳理下。
public static void main(String[] args) {
Map map = new HashMap<>();
map.put("1", "a");
for (Map.Entry entry : map.entrySet()) {
System.out.println("k:" + entry.getKey() + "\tv:" + entry.getValue());
}
}
这是遍历hashMap常用的方式,可以看到for循环的是entrySet,但是看entrySet()方法中直接返回了一个entrySet,entrySet并没有存入数据过,那上面的遍历是怎么取到数据的?
答案就是编译器做了优化,会通过Iterator模式迭代遍历,最终操作的其实是hashmap底层结构中的table数组,并没有开辟新的空间。下面看下具体过程
1.看下上边代码对应的字节码指令(javap -verbose xx.class)。可以看到编译器优化之后最终通过Iterator遍历了,调用了hasNext和next方法。
2.entrySet方法返回的Set是EntrySet。EntrySet继承了AbstractSet,重写了iterator方法,最终使用的是EntryIterator迭代器,EntryIterator又继承了HashIterator,重新来next方法。在next方法中,调用了nextNode方法,nextNode中才是具体访问hashmap的table数组,获取元素。
3.debug验证下