Попытка здесь сделать его как можно более лямбда-потоком.
Сначала текущий код вопроса вернет пустой набор, если какой-либо критерий (бренд или категория) опущен.Если это не ошибка, а предполагаемое поведение, то имеет смысл проверить, так ли это, и быстро вернуть пустой набор.Таким образом, код может начинаться следующим образом:
final List<String> filterBrands = filterParams.getOrDefault("brand", Collections.emptyList()));
final List<String> filterCategories = filterParams.getOrDefault("categories", Collections.emptyList()));
if (filterCategories.isEmpty() || filterCategories.isEmpty()) {
return Collections.emptySet();
}
Вы можете избежать составления второго списка, если первый список пуст, но он добавляет несколько строк кода, и выигрыш, скорее всего, будет очень незначительным.
Для этого момента вы можете использовать другой подход к ответу - создать набор из двух критериев, а затем использовать пересечение.Однако, поскольку вы можете получить доступ к бренду, известному как производитель, непосредственно из Продукта, существует альтернатива, которая не требует явного создания экземпляров таких наборов, поэтому мы можем улучшить производительность в зависимости от соотношения размера возврата и каждого набора критериев.Таким образом, если результат - всего несколько продуктов ... скажем, 5, но каждый критерий или один из набора критериев может в конечном итоге составить несколько тысяч, вы можете сэкономить память или процессорный процессор, выполнив следующие действия:
final Set<String> manufacturers = filterBrands.stream()
.map(String::toLowerCase)
.collect(Collectors.toSet());
return filterCategories.stream()
.flatMap(this::getProductsByCategory)
.distinct() // optional but might be better performance
// if categories share products.
.filter(product -> manufacturers.contains(product.getManufacturer().toLowerCase()))
.collect(Collectors.toSet());