The logic inside is quite complicated, however, try this out:
public List <String> getProductNames(Hub hub, String requestedGroup) {
List<SupportedProduct> configuredProducts = repo.getSupportedProducts(hub);
// extract pairs:
// key=SupportedProduct::getProductName
// values=List with one activeCategoryName OR names of all the categories
Map<String, List<String>> namedActiveCategoryNamesMap = configuredProducts.stream()
.collect(Collectors.toMap(
SupportedProduct::getProductName,
p -> Optional.ofNullable(p.getCategoryDetails().getActiveCategoryName())
.map(Collections::singletonList)
.orElse(Optional.ofNullable(p.getCategoryDetails().getCategories())
.stream()
.flatMap(Collection::stream)
.map(Category::getName)
.collect(Collectors.toList()))));
// look-up based on the categories' names, group equality comparison and returning a List
return namedActiveCategoryNamesMap.entrySet().stream()
.filter(entry -> entry.getValue().stream()
.map(catName -> divisionRepo.getDivisionByCatName(catName))
.filter(Objects::nonNull)
.map(Division::getGroup)
.anyMatch(requestedGroup::equals))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
- I recommend splitting into separate methods for sake of readability (the best way to go).
- The verbose logics of
Optional
chains including two orElse
calls can be surely simplified, however, it gives you the idea.
- You can perform within one Stream using
Collectors.collectingAndThen
. In that case, I'd extract the Function finisher
elsewhere, example:
public List<String> getProductNames(Hub hub, String requestedGroup) {
return repo.getSupportedProducts(hub).stream()
.collect(Collectors.collectingAndThen(
Collectors.toMap(
SupportedProduct::getProductName,
categoryNamesFunction()),
productNamesFunction(requestedGroup)));
}
private Function<Map<String, List<String>>, List<String>> productNamesFunction(String requestedGroup) {
return map -> map.entrySet().stream()
.filter(entry -> entry.getValue().stream()
.map(divisionRepo::getDivisionByCatName)
.filter(Objects::nonNull)
.map(Division::getGroup)
.anyMatch(requestedGroup::equals))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
private Function<SupportedProduct, List<String>> categoryNamesFunction() {
return p -> Optional.ofNullable(p.getCategoryDetails().getActiveCategoryName())
.map(Collections::singletonList)
.orElse(Optional.ofNullable(p.getCategoryDetails().getCategories())
.stream()
.flatMap(Collection::stream)
.map(Category::getName)
.collect(Collectors.toList()));
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…