Iterable和Iterator
Iterator和Iterable的内部实现
iterator为Java中的迭代器对象,是能够对List这样的集合进行迭代遍历的底层依赖。而iterable接口里定义了返回iterator的方法,相当于对iterator的封装,实现了iterable接口的类可以支持for each循环。
Iterator接口主要方法如下:
|  |  | 
Iterator接口定义了boolean hasNExt()和E next()两个方法,而迭代的方式则取决于实现Iterator接口的方法中具体的实现。
Iterable接口的定义如下:
|  |  | 
List中实现了Iterable接口,所以可以调用Iterator中的hasNext()方法进行迭代
|  |  | 
也可以使用foreach循环进行迭代**(使用foreach需要实现Iterable接口)**
|  |  | 
foreach实现原理
java docs里面提到了foreach的实现,称之为The enhancedfor statement(增强型for循环)
|  |  | 
- #iis an automatically generated identifier that is distinct from any other identifiers (automatically generated or otherwise) that are in scope (§6.3) at the point where the enhanced- forstatement occurs.
#i是 一个自动生成的标识符,它和其他任何(自动生成之类的)标识符都不一样,#i会在foreach循环调用时在特定的作用域生成。
- If the declared type of the local variable in the header of the enhanced forstatement is a reference type, then TargetType is that declared type; otherwise, TargetType is the upper bound of the capture conversion (§5.1.10) of the type argument of I, orObjectif I is raw.
如果在foreach循环条件里传入了已经声明了类型的的本地变量,而且这个变量的类型是一个引用类型,那么TargetType就会变成这个变量的类型;否则,TargetType是I的一个上界,或者当I是原始类型比如(T A)时,这个变量的类型就为Object.
比如下面的例子:
|  |  | 
这段代码会被翻译为
|  |  | 
可见Java的foreach循环是依赖于Iterator迭代器接口实现的,foreach循环的实现调用了其中的iterator()、hasNext()和next()方法
Iterator和Iterable的关系
之所以要将Iterator再封装一层形成Iterable接口,是因为这样做可以使实现了Iterable的类内部再定义多个Iterator内部类,从而达到不同遍历方法的目的。例如LinkedList中的ListIterator和DescendingIterator两个内部类,就分别实现了双向遍历和逆序遍历。通过返回不同的Iterator实现不同的遍历方式,这样更加灵活。如果把两个接口合并,就没法返回不同的Iterator实现类了。
ListIterator的实现如下:
|  |  | 
DescendingIterator源码如下:
|  |  | 
可见,ListIterator()返回的是ListItr对象,而descendingIterator()返回的是DescendingIterator对象,这两个对象都实现了Iterator接口,从而实现了顺序不同的遍历。
参考资料: