内部迭代程序是否使用hasNext()和next()在Java中进行迭代



我正在学习内部迭代器,我知道内部迭代程序在后台管理迭代:

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循环更快?任何反馈都将被取消?

另请参阅接口IterableforEach的定义。两个构造都使用相同接口的不同方法。

从概念上讲,不同之处在于;增强循环";实现Iterable的类只创建Iterator,循环结构负责推进它(另请参阅此相关问题(。

当调用forEach时,类控制整个迭代过程,并可以选择最适合其底层数据结构的内容。例如,它可以避免创建Iterator对象,而是使用一些内部数组索引或类似的索引。

除此之外,它们应该是等效的。在大多数情况下,我不会期望性能有任何差异。

请参阅这个极好的答案,了解您可能想要使用forEach的一些其他原因,例如迭代同步集合时的额外一致性保证,以及它没有提供的内容,例如流控制(例如使用break短路(或对已检查异常的支持。

区别在于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是否决定如何遍历集合。

我不知道你从哪里得到的"增强for循环是一个外部迭代器";,但Iterable.forEach只是做了与您的第二个示例相同的事情(可以被覆盖,尽管我看不出有任何理由这样做(。

default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}

最新更新