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

时间:2019-01-18 19:21:29

标签: 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));
}

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

2 个答案:

答案 0 :(得分: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());

但是,与普通的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)));

答案 1 :(得分:5)

您可以使用单个迭代器来做到这一点:

<mat-select placeholder="Country" ngModel name="nationality [(ngModel)]="nationality">
  <mat-option *ngFor="let country of Countries" [value]="country.code" >
      <div>
        <img [src]="country.flag" [alt]="country.name">
        <p>{{ country.name }}</p>
      </div>
  </mat-option>
</mat-select>

您可以编写没有任何其他变量的循环体:

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;
  }
}

这利用了Java保证的从左到右的评估顺序,这意味着第一个 while (it.hasNext()) { sections.add(new LineSection(prev, prev = it.next())); } 在重新分配之前被评估。这可能不是最好的方法:在读取代码时,表达式内的副作用很容易被忽略;使用您习惯阅读的那一种。

使用这样的迭代器进行此操作比索引非prev列表实现(例如RandomAccess)更有效。