我有以下方法,它采用List<Point2D>
并为每个点之间的每一行创建Line2D
。
public List<Line2D> getAllPointToPointLines() {
List<Point2D> points = getAllPoints();
List<Line2D> lines = new ArrayList<>();
for (int i = 0; i < points.size(); i++) {
for (int j = i + 1; j < points.size(); j++) {
lines.add(new Line2D.Double(points.get(i), points.get(j)));
}
}
return lines;
}
要通过创建Line2D(pointA, pointB)
以及Line2D(pointB, pointA)
来避免重复行,内部循环初始化为外部循环的当前索引的一个以上。
我最接近使用流来达到此行为的方法是以下方法。
public List<Line2D> getAllPointToPointLines() {
return points.stream()
.flatMap(i -> points.stream().filter(j -> !i.equals(j))
.map(j -> new Line2D.Double(i, j))).collect(toList());
}
然而,由于上述原因,这当然会产生重复的行。
我使用以下代码测试了@Eugene的答案:
Stopwatch stopwatch = new Stopwatch();
stopwatch.start();
for (int i = 0; i < 100000; i++) {
points.getAllPointToPointLines();
}
stopwatch.stop();
System.out.println("Non-stream - " + stopwatch.getTimeString());
stopwatch.reset();
stopwatch.start();
for (int i = 0; i < 100000; i++) {
points.getAllPointToPointLinesStream();
}
stopwatch.stop();
System.out.println("Stream - " + stopwatch.getTimeString());
通过@fge提供的优化,原始方法的输出大约为150ms,替代流方法的输出大约为650ms。
答案 0 :(得分:4)
看起来你需要这样的东西(我还没有用你的用例编译完全)
int size = points.size();
IntStream.range(0, size)
.boxed()
.flatMap(i -> IntStream.range(i + 1, size)
.mapToObj(j -> new Line2D.Double(points.get(i), points.get(j))))
.collect(Collectors.toList());