<分区>
我知道我们可以使用 List.foreach
遍历,我们也可以使用List.stream.foreach
来遍历。我不明白在 Java8 中遍历哪个更好。
<分区>
我知道我们可以使用 List.foreach
遍历,我们也可以使用List.stream.foreach
来遍历。我不明白在 Java8 中遍历哪个更好。
最佳答案
forEach(Consumer)
方法在 Iterable
中声明Collection
和 List
扩展的接口(interface)。 forEach(Consumer)
的默认实现是:
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
如您所见,默认实现只是在 for-each 循环中调用 action
。 for-each 循环只是语法糖:
for (Iterator<?> iterator = iterable.iterator(); iterator.hasNext(); ) {
Object element = iterator.next();
// Do what you need to with element
}
除非您无权访问 for-each 循环中的 Iterator
。
Iterable
的特定实现可能会改变它实际迭代其元素的方式(它可能使用也可能不使用 Iterator
)但它几乎总是 归结为一些 for
或 while
循环。我说“几乎总是”是因为可能涉及某种类型的递归或链接。
现在,当您只是尝试迭代 List
时,使用 List.stream().forEach(Consumer)
会创建一个不必要的 Stream
对象> 按顺序。如果您确实需要以管道方式处理元素集合(例如映射、过滤、映射更多等等),您应该只使用流式 API。
因此,对于简单的迭代,使用 List.stream().forEach(Consumer)
的性能将低于简单的 List.forEach(Consumer)
调用在几乎所有情况下。性能提升很可能可以忽略不计,但“优化”并不过分是一个很容易解决的问题;特别是如果你一开始就没有犯“错误”。不要创建不需要的对象。
虽然简单地使用 for-each 循环而不是 forEach(Consumer)
可能会更好。它比功能更强大的对应物更容易阅读。
编辑
正如 Holger 在评论中提到的,Stream.forEach(Consumer)
与 Iterable.forEach(Consumer)
有一个相当大的区别:它不保证元素的相遇顺序。虽然 Iterable.forEach(Consumer)
的迭代顺序也没有为 Iterable
接口(interface)定义,但可以通过扩展接口(interface)(例如 List
)。但是,当使用 Stream
时,无论 Stream
的来源如何,都无法保证顺序。
如果您希望在使用 Stream
时保证顺序,您必须使用 Stream.forEachOrdered(Consumer)
。
关于java - Java8容器 `for each`和Stream `for each`有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50662697/
相关文章:
java - 将 Java 代码导入 Swift iOS 应用程序?
java - 如何在 String.replaceAll 中使用 RegEx 在搜索和替换时忽略中间字符
javascript - 为什么使用 "for...in"进行数组迭代是一个坏主意?
java - 专家错误 : element dependency can not have character children
java - 使用java web/Java EE设计并行计算应用程序
lambda - Sonar : lambda - Remove useless curly braces around statement