我正在学习内部迭代器,并且我了解到内部迭代器在后台管理迭代:
public void internalIterator(){
List<String> namesList = Arrays.asList("Tom", "Dick", "Harry");
namesList.forEach(name -> System.out.println(name));
}
但是我认为增强的for循环做了同样的事情:
public void enhancedForLoop(){
List<String> namesList = Arrays.asList("Tom", "Dick", "Harry");
for(String name : namesList){
System.out.println(name);
}
}
我知道增强的for循环在后台使用hasNext()和next()方法。增强的for循环是一个外部迭代器。那么为什么forEach()方法是内部迭代器呢?forEach()方法不是在后台使用hasNext()和next()方法吗?如何在backgorund中以与增强的for循环不同的方式管理迭代?使用forEach()迭代比使用增强型for循环更快吗?有任何反馈会被接受吗?
发布于 2020-08-26 13:21:14
还请参见接口forEach
的Iterable
定义。两个构造都使用相同接口的不同方法。
在概念上,区别在于在“增强的for循环”中,实现Iterable
的类只创建Iterator
,而循环构造负责推进它(也请参阅this related question)。
当调用forEach
时,类控制整个迭代过程,并可以选择最适合其底层数据结构的任何内容。例如,它可以避免创建Iterator
对象,而是使用一些内部数组索引或类似的。
除此之外,它们应该是等同的。在大多数情况下,我不会期望在性能上有任何差异。
请参阅this excellent answer,因为其他原因您可能希望使用forEach
,例如在迭代同步集合时提供额外的一致性保证,以及this one提到它没有提供的内容,例如流控制(例如使用break
的短路)或支持检查的异常。
发布于 2020-08-27 12:05:47
区别在于API的用户必须做什么。
差异
外部
当使用iterator()
时,管理遍历是用户的任务(您的任务):何时调用hasNext()
,何时调用next()
。迭代是由API的用户从API外部处理的。用户都迭代元素&使用元素。
内部
在使用forEach
时,API的任务是管理遍历。迭代在内部由处理,而不是由用户处理;用户只使用元素。
结论
hasNext()
和next()
是否被调用并不重要。重要的是谁调用hasNext()
和next()
-谁处理迭代,谁负责迭代器。
forEach
是内部的,因为用户无法控制元素的迭代方式。API处理它;迭代器是内部的。
iterator()
是外部的,因为用户必须定义迭代将如何发生。API传递给您迭代器,这就是API所做的全部工作。迭代器是外部的。
尽管forEach
在某些情况下使用iterator()
,但迭代器仍然是您正在使用的API ( List
)的内部。调用forEach
的人仍然只担心消耗元素。用户并不控制如何遍历元素,所以forEach
使用什么并不重要。
关于何时使用策略的建议
当您需要最基本的顺序迭代时,您将使用增强循环。
当需要更复杂的迭代时,可以使用iterator()
。
当您只担心使用元素时,您就会使用forEach
,并且不介意API决定如何遍历集合。
发布于 2020-08-26 13:14:26
我不知道你是从哪里得到“增强的for循环是一个外部迭代器”的,但是Iterable.forEach
只是做了与第二个例子相同的事情(可能会被重写,但我看不出有什么理由)。
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
https://stackoverflow.com/questions/63598395
复制相似问题