标签:strong cts 接口 res 结构 action 位置 for循环 null
在Java中,我们可以对List集合进行如下几种方式的遍历:
List<Integer> list = new ArrayList<>();
// 法一:普通for循环
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + ",");
}
//法二:迭代器遍历
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.print(it.next() + ",");
}
// for each遍历
for (Integer i : list) {
System.out.print(i + ",");
}
// 后面两种方式涉及到Java中的Iterator和Iterable对象
看Iterable和Iterator所处包位置,Collection接口必须继承java.lang.Iterable接口。
Iterator为Java中的迭代器对象,是能够对List这样的集合进行迭代遍历的底层依赖。
Iterable接口里定义了返回Iterator的方法,相当于对Iterator的封装,同时实现了Iterable接口的类可以支持for each循环。
JDK中 Iterator 接口源码:
public interface Iterator<E> {
boolean hasNext(); // 检查序列中是否还有元素
E next(); // 获取序列中下一个元素
default void remove() { // 将迭代器新返回的元素删除
throw new UnsupportedOperationException("remove");
}
// 1.8新增的Iterator接口中的默认方法,对集合中*剩余*的元素进行操作,直到元素完毕或者抛出异常;注意为“剩余”,即迭代中还剩余的部分
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
集合类都实现了这个接口, Iterator 是迭代器最简单的实现,使用Iterator iter = list.iterator()
就实现了迭代器(见上面引言的使用)
Iterable接口的源码:
public interface Iterable<T> {
Iterator<T> iterator(); // 方法iterator()返回了一个Iterator对象(各具体类返回的类型也不同)
// 1.8新加的方法,对每个元素执行特有操作,可使用Lambda表达式
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
// 1.8新方法,可分割迭代器,用于并行遍历元素
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
for each实现:为Java语法糖,也是依赖Iterator迭代器,编译器自动转化
for (Integer i : list);
for(Iterator iterator = list.iterator(); iterator.hasNext(); System.out.println(i)){
i = (Integer)iterator.next();
}
这里是使用到了设计模式中的迭代器模式
为什么用Iterator实现遍历?(为什么使用迭代器模式)
为什么一定要去实现Iterable这个接口而不直接实现Iterator接口?
因为next()或者hasNext() 都依赖于迭代器当前的迭代位置,如果Collection直接实现Iterator接口,势必导致集合对象中包含当前迭代位置的数据(指针)。
当集合在不同方法间被传递时,由于当前迭代位置不可预置,那么next()方法的结果会变成不可预知。
除非再为Iterator接口添加一个reset()方法,用来重置当前迭代位置。 但这样,Collection也只能同时存在一个当前迭代位置。
而Iterable则不然,每次调用都会返回一个从头开始计数的迭代器。,使得多个迭代器是互不干扰的。
为什么不直接将hasNext(),next()方法放在Iterable接口中,其他类直接实现就可以了?
为了使集合类可以有多种遍历方式。
标签:strong cts 接口 res 结构 action 位置 for循环 null
原文地址:https://www.cnblogs.com/snm511/p/14128621.html