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

2022-09-02 12:52:06

如何计算流过滤器的匹配项?我正在尝试将以下代码重构为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()));

我现在如何获取已应用的已过滤元素的计数?题外话:在旧代码中,我可以多次重用。如何通过流实现相同的效果?Integer id


答案 1

由于 是 副作用 函数, 您可以使用 :setValuepeek

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

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

题外话:在旧代码中,我可以多次重用 Integer id。如何通过流实现相同的效果?

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

像这样:

.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

在你的情况下,如果你留在一个节点流,你可以随时获取id。getId()


答案 2

推荐