次のクラスがあります。
public class Insurance {
...
}
public class Customer {
private List<Insurance> insurances;
public List<Insurance> getInsurances() {
return insurances;
}
...
}
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
のような一時的なコレクションに追加されないように)、ある種の削減を実行できますか?
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())