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循环)
|
|
#i
is 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 enhancedfor
statement occurs.
#i
是 一个自动生成的标识符,它和其他任何(自动生成之类的)标识符都不一样,#i
会在foreach循环调用时在特定的作用域生成。
- If the declared type of the local variable in the header of the enhanced
for
statement 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, orObject
if 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
接口,从而实现了顺序不同的遍历。
参考资料: