给出以下代码:
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));
map
和filter
是中间操作,forEach
是终端操作。只有在执行终端操作后,我们才能获得数据转换的结果。
有没有办法强制评估更加渴望并拥有某种中间结果 - 而不会破坏流操作链?例如,我想要列出“a-a”,“b-b”,“c-c”(这将是第一次中间操作的结果)。
答案 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));