Java 8急切地获得了中间流操作的结果

Ant*_*ton 4 java java-8 java-stream

给出以下代码:

List<String> list = Arrays.asList("a", "b", "c");
        list.stream()
        .map(s -> s + "-" + s)                 //"a-a", "b-b", "c-c"
        .filter(s -> !s.equals("b-b"))         //"a-a", "c-c"
        .forEach(s -> System.out.println(s));
Run Code Online (Sandbox Code Playgroud)

map并且filter是中间操作并且forEach是终端操作.只有在执行终端操作之后,我们才能获得数据转换的结果.

有没有办法迫使评估更加渴望并获得某种中间结果 - 不打破流操作链?例如,我想要列出"aa","bb","cc"(这将是第一次中间操作的结果).

Tag*_*eev 7

你可以使用peek:

List<String> allPairs = new ArrayList<>();
List<String> list = Arrays.asList("a", "b", "c");
    list.stream()
    .map(s -> s + "-" + s)                 //"a-a", "b-b", "c-c"
    .peek(allPairs::add)
    .filter(s -> !s.equals("b-b"))         //"a-a", "c-c"
    .forEach(s -> System.out.println(s));
Run Code Online (Sandbox Code Playgroud)

这样计算在终端操作之前仍然不会启动,但您可以在任何时候"拦截"流内容并以您喜欢的任何方式使用它.

但请注意,如果您的终端操作是短路的(例如findFirst):这样就不会传递所有元素peek.


Kon*_*kov 6

好吧......如果我正确理解你的问题,你必须在通过not equals "b-b"谓词过滤之前应用终端操作.然后,你应该调用.stream()中间结果,并做过滤:

List<String> list = Arrays.asList("a", "b", "c");
list.stream()
    .map(s -> s + "-" + s)           //"a-a", "b-b", "c-c"
    .collect(Collectors.toList())    //intermediate result
    .stream()
    .filter(s -> !s.equals("b-b"))   //"a-a", "c-c"
    .forEach(s -> System.out.println(s));
Run Code Online (Sandbox Code Playgroud)