Java 如何计算流过滤器上的匹配项?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29260288/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:41:32  来源:igfitidea点击:

How to count matches on a stream filter?

javajava-8java-stream

提问by membersound

How can I count the matches of a stream filter? I'm trying to refactor the following code to java8 stream:

如何计算流过滤器的匹配项?我正在尝试将以下代码重构为 java8 stream

//java7
int i = 0;
for (Node node : response.getNodes()) {
    Integer id = node.getId();
    if (id != null) {
        node.setContent("This is the id: " + id);
        i++;
    }
}

//java8
response.getNodes().stream()
    .filter(node -> node.getId() != null)
    .forEach(node -> node.setValue("This is the id: " + node.getId()));

How can I now get the count of filtered elements that were applied? Sidequestion: in the old code I can reuse the Integer idmultiple times. How can I achieve the same with streams?

我现在如何获得应用的过滤元素的数量?附带问题:在旧代码中,我可以Integer id多次重复使用。如何使用流实现相同的目标?

采纳答案by Alexis C.

Since setValueis a side-effect function, you can use peek:

由于setValue是副作用函数,您可以使用peek

long i = response.getNodes()
                 .stream()
                 .filter(node -> node.getId() != null)
                 .peek(node -> node.setValue("This is the id: " + node.getId()))
                 .count();

I'm not a fan of this approach because peak is meant to use for debugging purpose (this would do the trick). Note that in Java 9, count()may be able to not execute the stream pipeline if it can compute the count directly from the source (I don't think it's the case here, since you apply a filtering but it's good to keep it in mind).

我不喜欢这种方法,因为 peak 旨在用于调试目的(这可以解决问题)。请注意,在 Java 9 中,count()如果可以直接从源代码计算计数,则可能无法执行流管道(我认为这里不是这种情况,因为您应用了过滤,但最好记住它) .

Sidequestion: in the old code I can reuse the Integer id multiple times. How can I achieve the same with streams?

附带问题:在旧代码中,我可以多次重用 Integer id。如何使用流实现相同的目标?

It depends on your use-case, since the API doesn't have tuples your best chance is to create a class, let's say Tuple2, so that you can map each node to a new tuple and reuse the id.

这取决于您的用例,因为 API 没有元组,所以您最好的机会是创建一个类,例如Tuple2,这样您就可以将每个节点映射到一个新的元组并重用 id。

Something like:

就像是:

.stream().map(node -> new Tuple2<>(node, node.getId()).moreStreamOps(...);
                                                      ^
                                                      |
                 at that point you have a Stream<Tuple2<Node, Integer>> 
                 from which you can grab the id with Tuple2#getSecond

In your case, if you stay with a stream of nodes, you can just grab the id with getId()at any time.

在您的情况下,如果您使用节点流,则可以随时获取 id getId()