在什么情况下,我们应该在JDK 8中使用旧的foreach
循环而不是新的collection.forEach()
,还是最好的做法是转换每个 foreach
循环?是否存在重要的性能差异?
我能想到的唯一情况是,如果你想迭代数组而不想先将数组转换为列表。
答案 0 :(得分:2)
目前很难想到最佳实践,因为JDK 8尚未发布。但是,基于早期使用这些API,有一些有趣的观察结果。
forEach()
方法现在位于Iterable
,由Collection
继承,因此所有集合都可以使用forEach()
。
数组可以包含在Arrays.asList()
的集合中,也可以包含在Arrays.stream()
的流中。这些只是包装纸;他们不会将所有元素复制到新容器中。
关于性能,Iterable.forEach(action)
的默认实现只是通常的“增强的for-loop”,它创建一个迭代器并发出连续的hasNext()
和next()
调用并调用{{ 1}}循环中的方法。与裸露的增强型for循环相比,额外的方法调用有一些额外的开销,但它可能非常小。
我会在风格上做出选择,而不是表现。
将每个 enhanced-for循环转换为使用action
可能不值得。考虑:
forEach()
与
for (String s : coll) {
System.out.println("---");
System.out.println(s);
System.out.println("---");
}
如果lambda是真正的单行,那么它可能是值得的,但在我看来,coll.forEach(s -> {
System.out.println("---");
System.out.println(s);
System.out.println("---");
});
中的多行语句lambda并不比一个好的for循环更清晰。
但是,如果for循环的主体中有逻辑,或者它需要保持某种运行状态,那么将循环重新转换为流管道可能是值得的。请考虑此片段,该片段可查找集合中最长字符串的长度:
forEach()
使用lambdas和流库重写,它看起来像这样:
int longest = -1;
for (String s : strings) {
int len = s.length();
if (len > longest)
longest = len;
}
当然,这是新的,不熟悉的,但在使用了一段时间之后,我发现它简洁易读。