IntelliJ IDEA 建议用 foreach 方法替换 for 循环。如果可能的话,我应该总是这样做吗?
IDEA建议替换,例如,这个:
for (Point2D vertex : graph.vertexSet()) {
union.addVertex(vertex);
}
有了这个:
graph.vertexSet().forEach(union::addVertex);
这个新版本肯定更具可读性。但是,在某些情况下,我最好坚持使用良好的旧语言结构来迭代,而不是使用新方法吗?foreach
例如,如果我理解正确,方法引用机制意味着构造一个匿名对象,否则(使用语言构造)将无法构造。这是否会成为某些操作的性能瓶颈?Consumer
for
所以我写了这个不是很详尽的基准测试:
package org.sample;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.infra.Blackhole;
import org.tendiwa.geometry.Point2D;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class LanguageConstructVsForeach {
private static final int NUMBER_OF_POINTS = 10000;
private static final List<Point2D> points = IntStream
.range(0, NUMBER_OF_POINTS)
.mapToObj(i -> new Point2D(i, i * 2))
.collect(Collectors.toList());
@Benchmark
@Threads(1)
@Fork(3)
public void languageConstructToBlackhole(Blackhole bh) {
for (Point2D point : points) {
bh.consume(point);
}
}
@Benchmark
@Threads(1)
@Fork(3)
public void foreachToBlackhole(Blackhole bh) {
points.forEach(bh::consume);
}
@Benchmark
@Threads(1)
@Fork(3)
public List<Point2D> languageConstructToList(Blackhole bh) {
List<Point2D> list = new ArrayList<>(NUMBER_OF_POINTS);
for (Point2D point : points) {
list.add(point);
}
return list;
}
@Benchmark
@Threads(1)
@Fork(3)
public List<Point2D> foreachToList(Blackhole bh) {
List<Point2D> list = new ArrayList<>(NUMBER_OF_POINTS);
points.forEach(list::add);
return list;
}
}
并得到:
Benchmark Mode Samples Score Error Units
o.s.LanguageConstructVsForeach.foreachToBlackhole thrpt 60 33693.834 ± 894.138 ops/s
o.s.LanguageConstructVsForeach.foreachToList thrpt 60 7753.941 ± 239.081 ops/s
o.s.LanguageConstructVsForeach.languageConstructToBlackhole thrpt 60 16043.548 ± 644.432 ops/s
o.s.LanguageConstructVsForeach.languageConstructToList thrpt 60 6499.527 ± 202.589 ops/s
在这两种情况下,为什么更有效率:当我几乎什么都不做和做一些实际工作时?不是简单地封装?这个基准测试是否正确?如果是这样,今天有什么理由在Java 8中使用旧语言结构吗?foreach
foreach
Iterator