如何从连续点列表中创建节列表

Krz*_*tof 3 java functional-programming

经典的for循环很容易解决这个问题

for (i = 0; i < points.size() - 1; i++) {
    PointAG p1 = this.points.get(i);
    PointAG p2 = this.points.get(i + 1);
    sections.add(new LineSection(p1, p2));
}
Run Code Online (Sandbox Code Playgroud)

是否有可能以功能的方式实现相同的功能,例如使用两个迭代器?

And*_*eas 5

取决于所说的"功能性方式".

如果您的意思是"使用流",那么以下可能是一种方式:

List<LineSection> sections = IntStream.range(1, points.size())
        .mapToObj(i -> new LineSection(this.points.get(i - 1), this.points.get(i)))
        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

但这并不比普通for循环更简单或更容易阅读,为什么呢?

List<LineSection> sections = new ArrayList<>();
for (int i = 1; i < points.size(); i++)
    sections.add(new LineSection(this.points.get(i - 1), this.points.get(i)));
Run Code Online (Sandbox Code Playgroud)


And*_*ner 5

您可以使用单个迭代器来执行此操作:

Iterator<PointAG> it = points.iterator();
if (it.hasNext()) {
  PointAG prev = it.next();
  while (it.hasNext()) {
    PointAG next = it.next();
    sections.add(new LineSection(prev, next));
    prev = next;
  }
}
Run Code Online (Sandbox Code Playgroud)

你可以编写循环体而不需要任何额外的变量:

  while (it.hasNext()) {
    sections.add(new LineSection(prev, prev = it.next()));
  }
Run Code Online (Sandbox Code Playgroud)

这利用了Java的保证从左到右的评估顺序,这意味着prev在重新分配之前评估第一个.这可能不是最好的方法:在阅读代码时,表达式中的副作用很容易被忽略; 使用你很舒服的阅读.

例如,这样做 - 使用迭代器 - 比非RandomAccess列表实现的索引更有效LinkedList.