给出以下功能:
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的过滤器,或者某种方式在单个流中执行此操作,那就太棒了。
答案 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());