java - 通过两个参数进行流过滤

标签 java java-stream predicate

我用谷歌搜索了很多,但没有找到答案。 这是我所拥有的:

    parentList.forEach(p -> {
        childList
                .stream()
                .filter(c -> p.id() == c.parentId())
                .<...continue working on stream...>
    });

我找不到用谓词替换“过滤器”部分的方法,因为我似乎需要将参数传递给谓词?

最佳答案

你的问题是你每次都使用不同的谓词,因为尽管 c是谓词的参数,p也各不相同:

final Node p;
Predicate<Node> matchesParentId = c -> p.id() == c.id();

现有代码编译正常的原因是 pforEach 的范围内有效地结束 block ,因此它可以用作 Predicate 中的最终字段在那个范围内,生命周期为一个 forEach迭代。

你可以这样做:

parentList.forEach(p -> {
    childList
            .stream()
            .filter(matchesId(p))
            .<...continue working on stream...>
});

private Predicate<Node> matchesId(Node other) {
     return node -> node.id() == other.id();
}

但您将无法创建 Predicate并将其重用为 p变化。


你可以写一个 BiPredicatecurry它变成了Predicate .遗憾的是,Java 不提供 curry 方法,因此您必须提供自己的方法。

private <T,U> Predicate<U> curry(BiPredicate<T,U> biPredicate, T t) {
    return u -> biPredicate.test(t, u);
} 

BiPredicate<Node,Node> nodesMatch = (a,b) -> a.id() == b.id();

parentList.forEach(p -> {
    childList
        .stream()
        .filter(curry(nodesMatch, p))
        .<...continue working on stream...>
});

这并没有给你带来比以前的解决方案更多的东西,但它有点像 FP Nerd 。您仍在创建一个新的 Predicate对于每个 p .当然你可以内联它而不是使用 curry()方法。

.filter(c -> nodesMatch.test(p, c))

这确实意味着您可以选择 BiPredicate<Node,Node> s 动态插入。如果你的BiPredicate初始化很昂贵,很多Predicates通过柯里化(Currying)包裹它会很便宜。


或者,您可以映射 pc到单个对象中,这允许您将整个事物提交给谓词:

Predicate<Pair<Node,Node>> nodesMatch = pair -> 
    pair.left().id() == pair.right().id();

parentList.forEach(p -> {
    childList
        .stream()
        .map(c -> new Pair<Node>( c, p))
        .filter(nodesMatch)
        .map( pair -> pair.left() )
        .<...continue working on stream...>
});

(这里的 Pair 是假设的,但是许多第 3 方库(例如 Guava)提供了一个,或者自己滚动,或者使用 new Node[] { c, p } )

关于java - 通过两个参数进行流过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46177748/

相关文章:

Java 8 泛型和类型推断问题

c# - 我如何将这个谓词定义为一个函数?

使用 Stream 的 Java 8 模式谓词 - 如何推断变量?

Angular 拖放 : can Enter predicate verify at which index the item is dropped?

Java - 在循环中打印逗号

java - “找不到或加载主类”是什么意思?

java JComboBox问题

java - 配置bean未初始化

java - jooq 和 java 8 流 SQL 生成

java - 如何使用 Java 8 中的 lambda 和流检查整数类型的所有元素是否在给定范围内?