【问题标题】:list of ancestors as stream祖先列表作为流
【发布时间】:2018-07-31 20:17:32
【问题描述】:

如何在 Java 8 中将此 while 循环转换为流?

    Location toTest = originalLocation;
    while(true){
        toTest = toTest.getParentLocation();
        if (toTest==null) {
            break;
        }
        parents.add(toTest);
    }

假设 Location 是这样的:

@Data
public class Location{
    private String name;
    private Location parentLocation;
}

好像应该是这样的:

Stream.iterate(location, l -> l.getParentLocation()).collect(Collectors.toList());

但是我给了我一个 NullPointerException。我假设是getParentLocation() 返回 null...

谁能帮忙?

【问题讨论】:

  • 什么是location,什么是parents
  • 该代码不会永远循环吗?我的意思是,location 永远不会更新,我认为它不是有状态的,所以getParentLocation() 总是返回相同的值。我认为您需要在循环结束时使用location = l;
  • 是的.. doh。让我更新一下。
  • while ((location = location.getParentLocation()) != null) parents.add(location); 呢?
  • 当然,是的。如何在 java 8 中将其转换为流?

标签: java java-8


【解决方案1】:

JDK9解决方案:

Stream.iterate(location, Objects::nonNull, Location::getParentLocation)
      .collect(Collectors.toList());

【讨论】:

  • generate 将永远“重复”location 的父级,因为location::getParentLocation 将始终返回相同的实例 - 它不会在每次迭代后将位置更改为其父级
  • @CarlosHeuberger 看到 OP 的最初帖子,这就是原因。从那以后我一直在编辑它。
  • 仍然是第一个将永远循环......而且很难理解,因为 OP 编辑​​了初始帖子
【解决方案2】:

您正在寻找的是来自 java-9 的 takeWhile

...takeWhile( x -> x != null).collect...

【讨论】:

  • @Aomine IIRC 有一个来自 Holger 的用于 java-8 的后端端口,但很难在手机上搜索
  • @Eugene 也许,你的意思是this one...
【解决方案3】:

使用 Java 9 中添加的 iterate​(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next) 重载:

Stream.iterate(location, l -> l != null, l -> l.getParentLocation())
      .collect(Collectors.toList());

同样使用方法引用:

Stream.iterate(location, Objects::nonNull, Location::getParentLocation)
      .collect(Collectors.toList());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-03
    • 2016-09-10
    • 2011-01-27
    • 1970-01-01
    相关资源
    最近更新 更多