[英]Java 8 eagerly get the result of an intermediate stream operation
Given the following code: 给出以下代码:
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
and filter
are intermediate operations and forEach
is a terminal operation. map
和filter
是中间操作, forEach
是终端操作。 Only after the execution of the terminal operation we can have the result of the data transformation. 只有在执行终端操作之后,我们才能获得数据转换的结果。
Is there any way to force the evaluation to be more eager and to have some kind of intermediate result - without breaking the stream operations chain? 有没有办法迫使评估更加渴望并获得某种中间结果 - 不打破流操作链? For example I want to have the list of "aa", "bb", "cc" (which would be the result of the first intermediate operation).
例如,我想要列出“aa”,“bb”,“cc”(这将是第一次中间操作的结果)。
You can use peek
: 你可以使用
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));
This way the computation still won't start until the terminal operation, but you can "intercept" the stream content at any point and use it in any way you like. 这样计算在终端操作之前仍然不会启动,但您可以在任何时候“拦截”流内容并以您喜欢的任何方式使用它。
Beware however if your terminal operation is short-circuiting (like findFirst
): this way not all the elements might be passed to peek
. 但是当心,如果你的终端操作是短路(如
findFirst
):这种方式不是所有的元素可能被传递给peek
。
Well ... if I understand your question correctly, you have to apply a terminal operation, before filtering by the not equals "bb"
predicate. 好吧......如果我正确理解你的问题,你必须应用终端操作,然后通过
not equals "bb"
谓词进行过滤。 Then, you should call .stream()
on the intermediate result and do the filtering: 然后,您应该在中间结果上调用
.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));
As Anton and kocko already stated, you can add your own collector, or use the Stream.collect method with the supplier, accumulator and combiner params: 正如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));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.