标签:abs extend nal col 迭代 title png 字段 基本
前言:如果对java的集合的遍历(主要是HashMap中的keySet() 和 entrySet()是如何取值并且可以实现遍历的)不是很明白的话,有兴趣深入了解的小伙伴,本文可以作为一个参考,由于时间的原因,就着重讲其遍历的核心代码,底层迭代器的分析。如果对集合的遍历已经迭代器没有基本的理解的话,建议先看看相关的文章;不然很难看懂本文。推荐几篇相关博文:
1.实在没想到系列——HashMap实现底层细节之keySet,values,entrySet的一个底层实现细节
2.Java迭代器深入理解及使用
3.Java集合框架中迭代器Iterator解析
由于ArrayList的迭代器实现比较简单,这里不赘述,主要讲讲HashMap的迭代器,以HashMap的entrySet()方法为例:
1.先看一下代码及其运行结果:
如果你点开entrySet()的代码一看,你就会觉得很神奇,如果你现在无感,那么你还是先看看这篇博文吧【1.实在没想到系列——HashMap实现底层细节之keySet,values,entrySet的一个底层实现细节 】(为了方便描述,将该博文称为博文1,其他类推)。那么现在分析一下,为什么entrySet()可以实现将map中值取出来呢,现在按步骤分析如下(以源码的查看为线索):
1.1 查看HashMap源码,定位到entrySet()方法:
1.2 注意到此处返回的是一个EntrySet对象,那么定位到EntrySet对象:
1.3 这时候你再怎么深入去定位你都会发现压根找不到有明显返回map中的值的地方,具体参考博文1,里面讲得很清楚;然后请注意截图中红色圈出的地方,注意到有一个iterator()方法,这就是关键所在,这时候请先参考博文2和博文3,以便理解后面的分析。到这里我们很清楚肯定是map调用了迭代器才使得可以取出map中相关的值(比如Set<Map.Entry<Integer, Integer>> set = map.entrySet();取出值:[1=11, 2=22, 3=33]),但不要误认为set本身并没有什么变量或者字段保存了map中的值,而是在System.out.println(set);的时候,set调用了toString()方法,而toString()方法中调用(循环调用)了iterator()方法,从而遍历获取了map中的底层数组table(不懂的自己先查阅资料)中的值,这句话不是很理解没关系,我们先分析一下EntrySet对象的继承关系:
final class EntrySet extends AbstractSet<Map.Entry<K,V>> {...}
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {...}
public abstract class AbstractCollection<E> implements Collection<E> { .... public String toString() { Iterator<E> it = iterator(); if (! it.hasNext()) return "[]"; StringBuilder sb = new StringBuilder(); sb.append(‘[‘); for (;;) { E e = it.next(); sb.append(e == this ? "(this Collection)" : e); if (! it.hasNext()) return sb.append(‘]‘).toString(); sb.append(‘,‘).append(‘ ‘); } } .. }
标签:abs extend nal col 迭代 title png 字段 基本
原文地址:http://www.cnblogs.com/chxbar/p/7457248.html