简体   繁体   English

为什么实例方法的Java方法引用无法分配给Consumer接口

[英]Why Java Method Reference of instance method cannot be assigned to Consumer interface

Here is my Code : 这是我的代码:

public class SearchByLambda {

     private Map<String,Consumer<Person>> searchCritertiaHolder = new HashMap<String,Consumer<Person>>();

     private static final String AGED = "aged";

     public SearchByLambda(){
           searchCritertiaHolder.put(AGED, (Person p)-> {p.filterAgedPerson(p);} );
     }

     private Consumer<Person> getFilter(String personType){
          return searchCritertiaHolder.get(personType);
     }

     public static void main(String[] args) {
          SearchByLambda searchUsage = new SearchByLambda();
          Person p = new Person(59,"shailesh");
          Person p1 = new Person(58,"ganesh");

          searchUsage.getFilter(AGED).accept(p);
          searchUsage.getFilter(AGED).accept(p1);

          Person.printAgedPersons();
     }
 }

 class Person{

       private static List<Person> agedPersons = new ArrayList<>();

       private int age;

       private String name;

       public int getAge() {
              return age;
       }

       public void setAge(int age) {
          this.age = age;
       }

       public String getName() {
            return name;
       }

       public void setName(String name) {
            this.name = name;
       }

       public Person(int age,String name){
           this.age = age;
           this.name = name;
       }

       public void filterAgedPerson(Person person){
          if(person.getAge() > 58){
              agedPersons.add(person);
          }
       }

       public static void printAgedPersons(){
            for(Person person : agedPersons){
                System.out.println(person.getName());
            }
       }
 }

When I replace following Lambda expression 当我替换以下Lambda表达式时

     searchCritertiaHolder.put(AGED, (Person p)-> {p.filterAgedPerson(p);});

with

              searchCritertiaHolder.put(AGED, Person::filterAgedPerson);

it gives me compilation error. 它给了我编译错误。 I am using java 8 and and compiling through eclipse. 我正在使用java 8并通过eclipse进行编译。 Why is this so? 为什么会这样? Why cannot I assign method reference for instance method of any arbitrary object to consumer functional interface? 为什么我不能将任意对象的实例方法的方法引用分配给消费者功能接口?

Your definition of filterAgedPerson takes a Person as an argument, even though it is not a static method. 您对filterAgedPerson定义将Person作为参数,即使它不是静态方法。 It doesn't need to, and it shouldn't if you want to use it as a Consumer<Person> . 它不需要,如果你想将它用作Consumer<Person> ,它就不应该。 What you are ending up with is something compatible with BiConsumer<Person, Person> . 你最终得到的是与BiConsumer<Person, Person>兼容的东西。

It might help to think of it this way: method references to non-static methods always take an "extra" argument which is used as this . 以这种方式思考它可能会有所帮助:对非静态方法的方法引用总是采用“额外”参数,并将其用作this参数。

The easiest way for you to fix this with your current code structure is to modify the filterAgedPerson method to not take a Person as an argument 使用当前代码结构修复此问题的最简单方法是修改filterAgedPerson方法,不要将Person作为参数

   public void filterAgedPerson() {
      if (this.getAge() > 58) {
          agedPersons.add(person);
      }
   }

As an aside, you might want to also consider making your filters Predicate<Person> instead of Consumer<Person> and moving the results handling elsewhere. 顺便说一句,您可能还想考虑使用过滤器Predicate<Person>而不是Consumer<Person> ,并将结果处理移动到其他地方。 This will give you more flexibility as things get more complicated. 随着事情变得更加复杂,这将为您提供更大的灵活性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM