在返回之前过滤集合流内的集合流

时间:2015-05-12 16:50:42

标签: java lambda collections java-8 java-stream

背景资料

我有以下课程:

保险

public class Insurance {
    ...
}

客户

public class Customer {
    private List<Insurance> insurances;

    public List<Insurance> getInsurances() {
        return insurances;
    }
    ...
}

CustomerRegistry

public class CustomerRegistry {
    private List<Customer> customers;
    ...
}

以及此辅助方法,可将List<Predicate<T>>缩减为单个Predicate<T>

public Predicate<T> reducePredicates(List<Predicate<T>> predicates) {
    return predicates.stream()
                     .reduce(Predicate::and)
                     .orElse(p -> true);
}

问题

我想要做的是获取与过滤器列表匹配的保险列表,这些过滤器属于与过滤器列表匹配的客户。如果不清楚,下面的代码将有希望澄清。

方法在上面的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;
}

如果没有matches列表,有没有办法做到这一点?我可以执行某种减少,以便直接返回匹配的保险(即不添加到matches这样的临时集合中吗?

1 个答案:

答案 0 :(得分:10)

使用flatMap():

customers.stream()
         .filter(reducePredicates(cusPredicates))
         .flatMap(cus -> cus.getInsurances().stream())
         .filter(reducePredicates(insPredicates))
         .collect(Collectors.toList())

或者更好,避免一遍又一遍地减少谓词:

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())