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

时间:2015-05-14 07:34:03

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

mapfilter是中间操作,forEach是终端操作。只有在执行终端操作后,我们才能获得数据转换的结果。

有没有办法强制评估更加渴望并拥有某种中间结果 - 而不会破坏流操作链?例如,我想要列出“a-a”,“b-b”,“c-c”(这将是第一次中间操作的结果)。

3 个答案:

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

这样计算仍然不会开始直到终端操作,但你可以&#34;拦截&#34;任何一点的流内容,并以您喜欢的任何方式使用它。

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

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

答案 2 :(得分:0)

正如Anton和kocko已经说过的,您可以添加自己的收集器,或者将Stream.collect方法与供应商,累加器和组合器参数一起使用:

    List<String> intermediateList = new ArrayList<>();
    List<String> list = Arrays.asList("a", "b", "c");
    list.stream().map(s -> s + "-" + s) // "a-a", "b-b", "c-c"
            .collect(() -> intermediateList, // supplier returns your intermediateList
                    (l, x) -> l.add(x), // accumulator - adds the element to your list
                    (l1, l2) -> {} // l1 and l2 are the same list, i guess - nothing to combine
            ) 
            .stream().filter(s -> !s.equals("b-b")) // "a-a", "c-c"
            .forEach(s -> System.out.println(s));