【问题标题】:Pass function as parameter to Lambda java 8 [duplicate]将函数作为参数传递给 Lambda java 8 [重复]
【发布时间】:2021-04-14 05:40:00
【问题描述】:

我有以下方法:

public String getAllDangerousProductsName(Offer offer){
    return offer.getOfferRows().stream()
           .filter(row -> row.isDangerousGood())
            .map(row -> row.getItemInformation().getOfferTexts().getName())
            .collect(Collectors.joining(","));
}

我想将此方法用于 row.isBulkyGood()。我目前正在做的是

public String getAllBulkyProductsName(Offer offer){
    return offer.getOfferRows().stream()
            .filter(row -> row.isBulkyGood())
            .map(row -> row.getItemInformation().getOfferTexts().getName())
            .collect(Collectors.joining(","));
}

... 这基本上是代码重复。有没有办法可以将函数作为方法参数传递来优化它,以便为两种过滤条件提供一种方法?

【问题讨论】:

    标签: java lambda java-8 java-stream


    【解决方案1】:

    您可以将过滤器中使用的Predicate 传递给方法,这是方法中唯一不同的地方。

    假设offer.getOfferRows() 返回List<OfferRow>,那么:

    public String getAllDangerousProductsName(Offer offer, Predicate<OfferRow> predicate) {
        return offer.getOfferRows().stream()
                .filter(predicate)
                .map(row -> row.getItemInformation().getOfferTexts().getName())
                .collect(Collectors.joining(","));
    }
    

    使用变得相当简单:

    // using lambda expression
    String str1 = getAllDangerousProductsName(offer, row -> row.isDangerousGood());
    String str2 = getAllDangerousProductsName(offer, row -> row.isBulkyGood());
    
    // using method reference
    String str1 = getAllDangerousProductsName(offer, OfferRow::isDangerousGood);
    String str2 = getAllDangerousProductsName(offer, OfferRow::isBulkyGood);
    

    【讨论】:

      【解决方案2】:

      是的,您可以在此方法中添加Predicate&lt;OfferRow&gt; 参数,然后使用方法引用OfferRow::isDangerousGoodOfferRow::isBulkyGood

      public static String getAllProductsNameByPredicate(Offer offer, Predicate<OfferRow> predicate){
          return offer.getOfferRows().stream()
                  .filter(predicate)
                  .map(row -> row.getName())
                  .collect(Collectors.joining(","));
      }
      
      // invoke with different predicates
      getAllProductsNameByPredicate(myOffer, OfferRow::isDangerousGood);
      getAllProductsNameByPredicate(myOffer, OfferRow::isBulkyGood);
      

      如果需要否定谓词的条件,Java 11 起可以使用Predicate.not

      对于 Java 8-10,可以使用 Predicate.negate() 实现实用方法:

      public static <R> Predicate<R> not(Predicate<R> predicate) {
          return predicate.negate();
      }
      
      getAllProductsNameByPredicate(myOffer, not(OfferRow::isDangerousGood));
      
      

      【讨论】:

        【解决方案3】:

        是的,创建一个filterAndJoin

        public String filterAndJoin(Offer offer, Predicate<Row> predicate){
            return offer.getOfferRows().stream()
                .filter(predicate)
                .map(row -> row.getItemInformation().getOfferTexts().getName())
                .collect(Collectors.joining(","));
          }
        

        然后将调用更改为

        public String getAllDangerousProductsName(Offer offer){
            return filterAndJoin(offer, Row::isBulkyGood);
        }
        

        【讨论】:

          猜你喜欢
          • 2020-08-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-26
          • 2020-05-13
          • 2013-01-27
          • 2016-04-16
          • 2014-03-07
          相关资源
          最近更新 更多