Vararg用java 8流预测

时间:2015-10-02 04:21:50

标签: java functional-programming java-8 java-stream

给出以下功能:

public static <X> List<X> filterWithVarargPredicates(
        List<X> allProducts,
        Predicate<X>... predicates
    ) {
        for (Predicate<X> predicate : predicates) {
            allProducts = allProducts.stream()
                .filter(predicate)
                .collect(toList());
        }

        return allProducts;
    }

有没有办法消耗所有谓词而不必循环遍历它们并重新分配到列表?例如,如果.stream()有一个采用varargs的过滤器,或者某种方式在单个流中执行此操作,那就太棒了。

3 个答案:

答案 0 :(得分:3)

我可以建议创建一个结合所有其他的新谓词:

Predicate<X> allPredicates = x -> Arrays.stream(predicates)
          .mapToInt(predicate -> !predicate.test(x)? 1: 0).sum()==0;
allProducts = allProducts.stream().filter(allPredicates).collect(toList());

修改 来自@Holger的更好方法回答How to apply multiple predicates to a java.util.Stream?

Predicate<X> allPredicates = Arrays.stream(predicates)
                                   .reduce(Predicate::and)
                                   .orElse(x->true);

答案 1 :(得分:1)

我会写一个方法将许多谓词合并为一个。

@SafeVarargs
static <T> Predicate<T> allTrue(Predicate<? super T>... predicates) {
    return t -> {
        for (Predicate<? super T> predicate : predicates)
            if (!predicate.test(t))
                return false;
        return true;
    };
}

然后你可以这样做:

allProducts.stream()
           .filter(allTrue(predicates))
           .collect(Collectors.toList());

答案 2 :(得分:0)

确实如此。流是普通对象 - 您可以将它们存储在变量等中。

    Stream<X> stream = allProducts.stream();
    for (Predicate<X> predicate : predicates) {
        stream = stream.filter(predicate);
    }

    return stream.collect(toList());