java 在返回之前过滤集合流内的集合流
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30196997/
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
Filtering collection stream inside collection stream before returning
提问by Martin M J
Background information
背景资料
I've got the following classes:
我有以下课程:
Insurance
保险
public class Insurance {
...
}
Customer
顾客
public class Customer {
private List<Insurance> insurances;
public List<Insurance> getInsurances() {
return insurances;
}
...
}
CustomerRegistry
客户登记处
public class CustomerRegistry {
private List<Customer> customers;
...
}
as well as this helper method, which reduces a List<Predicate<T>>
into a single Predicate<T>
:
以及这个辅助方法,它将 aList<Predicate<T>>
简化为单个Predicate<T>
:
public Predicate<T> reducePredicates(List<Predicate<T>> predicates) {
return predicates.stream()
.reduce(Predicate::and)
.orElse(p -> true);
}
The problem
问题
What I want to do is get a list of insurances that match a list of filters, belonging to customers that match a list of filters. If this is unclear, the below code will hopefully clarify.
我想要做的是获取与过滤器列表匹配的保险列表,属于与过滤器列表匹配的客户。如果这不清楚,下面的代码有望澄清。
Method is inside CustomerRegistry
class above.
方法在CustomerRegistry
上面的类中。
public List<Insurance> findInsurances(List<Predicate<Customer>> cusPredicates,
List<Predicate<Insurance>> insPredicates) {
List<Insurance> matches = new LinkedList<>();
customers.stream()
.filter(reducePredicates(cusPredicates)
.forEach(cus -> cus.getInsurances()
.stream()
.filter(reducePredicates(insPredicates))
.forEach(cus -> matches.add(cus)))
return matches;
}
Is there a way to do this without the matches
list? Can I perform some sort of reduction, so that the matching insurances are returned directly (i.e. not being added to a temporary collection like matches
)?
有没有办法在没有matches
列表的情况下做到这一点?我是否可以执行某种减少,以便直接返回匹配的保险(即不会添加到像 那样的临时集合中matches
)?
采纳答案by JB Nizet
Use flatMap():
使用 flatMap():
customers.stream()
.filter(reducePredicates(cusPredicates))
.flatMap(cus -> cus.getInsurances().stream())
.filter(reducePredicates(insPredicates))
.collect(Collectors.toList())
Or better, to avoid reducing the predicates over and over again:
或者更好的是,为了避免一遍又一遍地减少谓词:
Predicate<Customer> customerPredicate = reducePredicates(cusPredicates);
Predicate<Customer> insurancePredicate = reducePredicates(insPredicates);
List<Insurance> =
customers.stream()
.filter(customerPredicate)
.flatMap(cus -> cus.getInsurances().stream())
.filter(insurancePredicate)
.collect(Collectors.toList())