takeWhile() 以不同的方式使用平面图解释

2022-08-31 13:22:17

我正在使用takeWhile创建片段,以探索其可能性。当与 flatMap 结合使用时,行为不符合预期。请在下面找到代码片段。

String[][] strArray = {{"Sample1", "Sample2"}, {"Sample3", "Sample4", "Sample5"}};

Arrays.stream(strArray)
        .flatMap(indStream -> Arrays.stream(indStream))
        .takeWhile(ele -> !ele.equalsIgnoreCase("Sample4"))
        .forEach(ele -> System.out.println(ele));

实际输出:

Sample1
Sample2
Sample3
Sample5

预期输出:

Sample1
Sample2
Sample3

期望的原因是 takeWhile 应该一直执行,直到里面的条件变为 true。我还在平面图中添加了打印输出语句以进行调试。流仅返回两次,这与预期是一致的。

但是,这在链中没有平面图的情况下工作得很好。

String[] strArraySingle = {"Sample3", "Sample4", "Sample5"};
Arrays.stream(strArraySingle)
        .takeWhile(ele -> !ele.equalsIgnoreCase("Sample4"))
        .forEach(ele -> System.out.println(ele));

实际输出:

Sample3

此处,实际输出与预期输出匹配。

免责声明:这些代码段仅用于代码练习,不提供任何有效的用例。

更新:Bug JDK-8193856:修复程序将作为 JDK 10 的一部分提供。更改将更正下沉::接受whileOps

@Override 
public void accept(T t) {
    if (take = predicate.test(t)) {
        downstream.accept(t);
    }
}

更改的实现:

@Override
public void accept(T t) {
    if (take && (take = predicate.test(t))) {
        downstream.accept(t);
    }
}

答案 1

这是 JDK 9 中的一个错误 - 来自问题 #8193856

takeWhile错误地假定上游操作支持并接受取消,不幸的是,对于 .flatMap

解释

如果流已排序,应显示预期的行为。在您的代码中并不完全如此,因为您使用了 ,这会免除顺序。如果您关心它(在此示例中执行此操作),则应改用。有趣的是:这不会改变任何事情。takeWhileforEachforEachOrdered


答案 2

推荐