foreach
从官方文档获悉,foreach 语法(糖)是为了取代对一个collection进行迭代器迭代操作而出现的,目的:代码美观、减少出错。始于java 1.5。
官网链接:https://docs.oracle.com/javase/8/docs/technotes/guides/language/foreach.html
注意: Collection Interface (即我们常说的集合) 不仅包括java.util.Collection还包括java.util.Map,虽然Map 不是一个真正的Collection,但是Map接口包括一系列collection-view operations, which enable them to be manipulated as collections.
总而言之,collection(首字母小写的)包括Collection接口和Map接口下的实现类,如下图蓝字所示。
Iterator
iterator 接口 的出现是为了遍历一个collection,替换掉Enumeration这个接口,他的优点主要是可以在 遍历的同时删除元素 。始于 java 1.2。
* An iterator over a collection. {@code Iterator} takes the place of
* {@link Enumeration} in the Java Collections Framework. Iterators
* differ from enumerations in two ways:
*
* <ul>
* <li> Iterators allow the caller to remove elements from the
* underlying collection during the iteration with well-defined
* semantics.
* <li> Method names have been improved.
* </ul>
Iterable
Iterable 接口 的出现是为了让 数组 和 集合 以外的object进行foreach loop的操作。始于 java 1.5
* Implementing this interface allows an object to be the target of
* the "for-each loop" statement. See
* <strong>
* <a href="{@docRoot}/../technotes/guides/language/foreach.html">For-each Loop</a>
* </strong>
梳理一下
Iterator接口在java1.2就有了,而foreach语法和Iterable接口java1.5同时出现。发展顺序:
- 为了能在遍历时删除元素,出现了Iterator接口;
- 为了简化Iterator代码,出现了foreach语法;
- 为了能使foreach遍历除了数组、集合之外的object,出现了Iterable。
结尾
使用foreach循环的对象可分为两种:
- 数组
- Iterable接口的实现类
对于数组,foreach采用for循环
对于Iterable接口的实现类,foreach采用迭代器方法
Iterable接口里面有个iterator()方法,返回一个Iterator对象。java 1.5 之后,Iterator接口不仅仅服务于collection,任何一个Iterable接口的实现类都要实现Iterator接口中的迭代操作。
以一个collection的源码为例:
public interface Collection<E> extends Iterable<E> {...}
// 迭代器方法的实现
public abstract class AbstractList<E> extends Collection<E> implements List<E> {
...
// 必须覆写Iterable接口中的iterator()方法
@override
public Iterator<E> iterator() {
return new Itr();
}
...
}
// 迭代操作的具体实现
private class Itr implements Iterator<E> {
// 必须覆写Iterator接口中的三个迭代操作的方法
@override
boolean hasNext(){...};
@override
E next(){...};
@override
void remove(){...};
}
以上。
Iterable表示一个标志,它标志着该类可以被迭代,它提供迭代器,用户需要迭代操作,就调用他的iterator()方法
Iterator定义了迭代操作的具体实现。
这两个接口实现了迭代器的获取和实现的解耦,实现了。
在回到foreach,foreach的出现就是为了简化迭代器,所以可以使用迭代器的都可以被foreach,进一步,实现了Iterable接口的都可以被foreach,且底层为Iterable接口中定义的iterator方法的迭代器遍历。那没实现foreach的呢?例如数组,就没有实现。数组的foreach,这就回到了结尾部分的开头,它的foreach底层使用的是一般的for循环。
所以,foreach像是一种语法糖,底层实现还是for循环和迭代器。