有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用lambdajava的多重过滤器

我正在尝试像这样过滤java集合:

filtered = products.stream()
                .filter((product) ->size!=null&& 
                 product.getSize().equalsIgnoreCase(size))
                .filter((product) ->firmness!=null  && 
                 product.getFirmness().equalsIgnoreCase(firmness))
                .collect(Collectors.toList());

在这个例子中,我有两个要过滤的变量-size&;坚定。此变量是可选的,可以为空。 因此,如果我发送两个NOTNULL参数,代码会正常工作,并且过滤良好,但是当我只发送一个参数,而将另一个参数设置为null时,它就不工作了。我需要我的集合被非空值过滤。因此,如果一个参数为null,另一个参数为null,则必须使用not null值对集合进行筛选。我怎么能做到这一点


共 (4) 个答案

  1. # 1 楼答案

    更新。多亏了shmosel的回答,在这个lambda示例中有一种更好的使用三元运算的方法:

    filtered = products.stream()
    .filter( size == null ? p -> true : p -> p.getSize().equalsIgnoreCase(size) )
    .filter( firmness == null ? p -> true : p -> product.getFirmness().equalsIgnoreCase(firmness) )
    .collect( Collectors.toList() );
    

    正如霍尔格提到的,将空校验移出lambda表达式将避免对每个product重复检查null,并避免不必要的捕获或sizefirmness当它们是null时,这有助于根据this提高性能

    以下是原始方法:

    filtered = products.stream()
    .filter( (product) -> size != null ? product.getSize().equalsIgnoreCase(size) : true )
    .filter( (product) -> firmness != null ? product.getFirmness().equalsIgnoreCase(firmness) : true )
    .collect( Collectors.toList() );
    
  2. # 2 楼答案

    另请看BlobCity java commons https://blog.blobcity.com/2018/07/15/retainif-and-removeif-for-java-collections-blobcity/中的CollectionUtil.retainIf(collection, predicate)

    CollectionUtil.retainIf(products, product -> product.getSize().equalsIgnoreCase(size));
    CollectionUtil.retainIf(products, product -> product.getFirmness().equalsIgnoreCase(firmness));
    

    每次调用都会减少原始列表,以仅保留那些满足谓词条件的值。如果需要,可以在谓词中添加空检查

  3. # 3 楼答案

    &&要求它为非空。使用||反转条件,例如

    size == null || product.getSize().equalsIgnoreCase(size)
    

    如果要避免对每个元素进行null检查,可以将整个lambda放在三元表达式中:

    .filter(size == null ? p -> true : p -> p.getSize().equalsIgnoreCase(size))
    
  4. # 4 楼答案

    像这样的东西,我还没有编译
    您甚至可以在开始管道处理之前计算Predicate

    static  Predicate<Product> predicate(String size, String firmness) {
         if(size != null && firmness != null){
             return p -> p.getSize().equalsIgnoreCase(size) 
                    && p.getFirmness().equalsIgnoreCase(firmness);
         } else if(size != null){
             return p -> p.getSize().equalsIgnoreCase(size); 
         } else if(firmness != null){
             return p -> p.getFirmness().equalsIgnoreCase(firmness);
         } else {
             return p -> false;
         }
     }