流中的非终端forEach()?

时间:2016-11-16 05:53:18

标签: java java-stream

有时在处理Java流()时,我发现自己需要使用非终端forEach()来触发副作用,但不会终止处理。

我怀疑我可以使用类似.map(item - > f(item))的方法执行此操作,其中方法f执行副作用并将项目返回到流中,但它似乎有点笨拙。

有没有一种标准的处理方式?

2 个答案:

答案 0 :(得分:12)

是的。它被称为peek()(来自JavaDoc的例子):

Stream.of("one", "two", "three", "four")
     .peek(e -> System.out.println("Original value: " + e))
     .filter(e -> e.length() > 3)
     .peek(e -> System.out.println("Filtered value: " + e))
     .map(String::toUpperCase)
     .peek(e -> System.out.println("Mapped value: " + e))
     .collect(Collectors.toList());

答案 1 :(得分:2)

不,没有。

peek()仅在通过以下操作强制执行时才对所有元素进行操作。你能预测这段代码会打印什么吗?

public class Test
{
    private static final AtomicBoolean FLAG = new AtomicBoolean(false);

    private static void setFlagIfGreaterThanZero(int val)
    {
        if (val > 0) {
            FLAG.set(true);
        }
    }

    public static void main(String[] args)
    {
        FLAG.set(false);

        // Test 1
        IntStream.range(0, 10)
                 .peek(Test::setFlagIfGreaterThanZero)
                 .findFirst();

        System.out.println(FLAG.get());
        FLAG.set(false);

        // Test 2
        IntStream.range(0, 10)
                 .peek(Test::setFlagIfGreaterThanZero)
                 .sorted()
                 .findFirst();

        System.out.println(FLAG.get());
        FLAG.set(false);

        // Test 3
        IntStream.range(0, 10)
                 .boxed()
                 .peek(Test::setFlagIfGreaterThanZero)
                 .sorted()
                 .findFirst();

        System.out.println(FLAG.get());
        FLAG.set(false);

        // Test 4
        IntStream.range(0, 10)
                 .peek(Test::setFlagIfGreaterThanZero)
                 .filter(x -> x == 0)
                 .toArray();

        System.out.println(FLAG.get());
    }
}

答案是:

  



真正

如果您对Java Streams有充分的了解,那么输出可能很直观,但希望它也表明依赖peek()作为中流forEach()是一个非常糟糕的主意。

map()也遭遇同样的问题。据我所知,没有Stream操作可以保证每个情况下的“处理每个元素而不采取快捷方式”的行为,而不依赖于先前和后续操作。

虽然这可能很痛苦,但Streams的短路行为是一个重要特征。您可能会发现这个优秀的答案非常有用:https://stackoverflow.com/a/32194320/507761