Java 嵌套列表上的流式多过滤器问题?

Java stream multiple filter problem on nested lists?

我有以下流可以正常工作:

final List<ProductCategoryDTO> productCategoryList = productCategoryService
                .findAllByMenu(menuUuid)
                .stream()
                .filter(category -> !category.getProductList().isEmpty())
                .collect(Collectors.toList());

我只想添加另一个过滤器:

final List<ProductCategoryDTO> productCategoryList = productCategoryService
                .findAllByMenu(menuUuid)
                .stream()
                .filter(category -> !category.getProductList().isEmpty())
                .flatMap(product -> product.getProductList().stream())
                .filter(menu -> !menu.getMenuItemProperties().isDisabled())
                .collect(Collectors.toList());

但是它抛出所需的类型是 List<ProductCategoryDTO> 并且返回的类型是 List<MenuItemCategoryDTO>。我还尝试通过向原始过滤器添加 && 条件来使用单个过滤器,但无法执行此操作。

.filter(category -> !category.getProductList().isEmpty() 
    && category.getProductList().stream()
   .filter(p -> !p.getMenuItemProperties().isDisabled()))

那么,对于这种情况,正确的用法是什么? productCategoryList 中有一个产品列表,我需要根据 menuItemProperties().isDisabled() 属性 进行筛选。有什么想法吗?

更新:


public class ProductCategoryDTO {
    private UUID uuid;
    private UUID menuUuid;
    private List<MenuItemCategoryDTO> productList;
}

您可以像这样使用 mapMulti(在 Java 16 中介绍)

  • 流式传输类别
  • 对于每个产品(如果存在)
    • 遍历该产品的属性
    • 继续迭代直到至少有一个是enabled
    • 然后接受将产品添加到流中的那个。
  • 然后return一个列表
List<ProductCategoryDTO> productCategoryList = productCategoryService
        .findAllByMenu(menuUuid)
        .stream()
        .<ProductCategoryDTO>mapMulti((category, consumer)-> {
               for(Product prod : getProductList()) {
                   if (prod.getMenuItemsProperties().isDisabled()) {
                       // check next product
                       continue;
                   }
                   // at least one enabled one found so accept category
                   consumer.accept(category);
                   break;
               } 
        }).collect(Collectors.toList());

如果您想确保在所有属性都启用的情况下只接受类别,您可以这样尝试。

List<ProductCategoryDTO> productCategoryList = productCategoryService
        .findAllByMenu(menuUuid)
        .stream()
        .<ProductCategoryDTO>mapMulti((category, consumer)-> {
               for(Product prod : getProductList()) {
                   if (prod.getMenuItemsProperties().isDisabled()) {
                       return;
                   }
               }
               // all are enabled so accept category
               consumer.accept(category);    
        }).collect(Collectors.toList());