微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Java Predicate<T> 如何允许没有参数的方法?

如何解决Java Predicate<T> 如何允许没有参数的方法?

根据我的研究,Predicate一个具有抽象方法 boolean test(T var1);函数式接口。因此,如果我使用 Java 8 的方法引用并将其传递给在类 getAllVegeteriandish(List<dish> dish,Predicate<dish> p 中定义的函数 Vegdish,如果我使用 getAllVegeteriandish(menu,dish :: isvegeterian); 作为 {{1} } 确实匹配isvegeterian()函数签名,作者在书中特别提到了这一点方法引用的签名必须匹配上下文的类型(这里的上下文是 Predicate,它具有接受 1 个参数的抽象方法 test)。

我从《现代 Java 实战》一书中提取了以下代码,稍作修改

boolean test(T var1)
package modernjavainaction.chap04;

import java.util.Arrays;
import java.util.List;

public class dish {

  private final String name;
  private final boolean vegetarian;
  private final int calories;
  private final Type type;

  public dish(String name,boolean vegetarian,int calories,Type type) {
    this.name = name;
    this.vegetarian = vegetarian;
    this.calories = calories;
    this.type = type;
  }

  public String getName() {
    return name;
  }

  public boolean isvegetarian() {
    return vegetarian;
  }

  public int getCalories() {
    return calories;
  }

  public Type getType() {
    return type;
  }

 

  public enum Type {
    MEAT,FISH,OTHER
  }

  @Override
  public String toString() {
    return name;
  }

  public static final List<dish> menu = Arrays.asList(
      new dish("pork",false,800,dish.Type.MEAT),new dish("beef",700,new dish("chicken",400,new dish("french fries",true,530,dish.Type.OTHER),new dish("rice",350,new dish("season fruit",120,new dish("pizza",550,new dish("prawns",dish.Type.FISH),new dish("salmon",450,dish.Type.FISH)
  );

}

编辑: 所以我发现我的理解存在差距,为了首先理解方法引用,我们应该知道它的等效 lambda 是什么,即,

package modernjavainaction.chap04;

import static java.util.stream.Collectors.toList;
import static modernjavainaction.chap04.dish.menu;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

public class Vegdish {

  public static void main(String[] args) {
  
      List<dish> res = getAllVegeteriandish(menu,dish :: isvegeterian);
      System.out.println(res);
  }


  public static List<dish> getAllVegeteriandish(List<dish> dish,Predicate<dish> p) {
      List<dish> vegan = new ArrayList<>();
      for(dish d : dish) {
          if(p.test(d)) {
              vegan.add(d);
          }
      }
      return vegan;
  }





其中 d 是 Veg 类中的任意对象。现在,如果您不知道任意对象是什么,请阅读 oracle 文档中不同类型的方法引用,然后查看“方法引用的种类”oracle docs for method reference 表。 让我告诉你我对“任意”一词的理解。这意味着您正在使用当前类中某个其他类的对象。因此,在我们的 lambda 示例中,我们在 Veg 类中使用 dish 类型的对象 d。

现在将 lambda 转换为这种类型的方法引用的规则是

List<dish> res = getAllVegeteriandish(menu,(dish d) -> d.isvegeterian());

现在使用上面的蓝图让我们用方法引用替换我们的 lambda args0 --> d instanceMethod() --> isvegeterian()

所以对应的Method引用是

            Lambda
            (args0) -> args0.instanceMethod()

            Method Reference
            ClassName :: instanceMethod

            where args0 is of type Class Name

上面的蓝图是我从《现代 Java 实战》一书中得到的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。