Я считаю, что подойдет любой из следующих двух подходов:
Этот первый использует Stream.concat
, что позволяет вам соединить два потока вместе.
Stream<BusinessCustomer> matches = customerRelationships.stream()
.flatMap(relationship -> customers.stream()
.filter(customer -> customer.getFirstName().equalsIgnoreCase(relationship.getFirstName()))
.map(customer -> new BusinessCustomer(relationship.getFirstName(), relationship.getLastName(), customer.getAge())));
Stream<BusinessCustomer> nonMatches = customerRelationships.stream()
.filter(relationship -> customers.stream().noneMatch(customer -> customer.getFirstName().equalsIgnoreCase(relationship.getFirstName())))
.map(relationship -> new BusinessCustomer(relationship.getFirstName(), relationship.getLastName()));
List<BusinessCustomer> result = Stream.concat(matches, nonMatches)
.collect(Collectors.toList());
В качестве альтернативы вы можете не создавать два промежуточных объекта matches
и nonMatches
Stream и просто поместить эти операторы в Stream.concat
.
Другой способ, который, я думаю, сработает, следующий:
customerRelationships.stream()
.flatMap(relationship -> {
boolean noneMatch = customers.stream().noneMatch(customer -> customer.getFirstName().equalsIgnoreCase(relationship.getFirstName()));
if (noneMatch) {
return Stream.of(new BusinessCustomer(relationship.getFirstName(), relationship.getLastName()));
} else {
return customers.stream()
.filter(customer -> customer.getFirstName().equalsIgnoreCase(relationship.getFirstName()))
.map(customer -> new BusinessCustomer(relationship.getFirstName(), relationship.getLastName(), customer.getAge()));
}
})
.collect(Collectors.toList());
Кроме того, мне еще предстоит протестировать эти два подхода, поэтому обязательно выполните их через свой собственный набор тестов.