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

时间:2015-10-18 22:40:49

标签: java lambda

这是我的代码:

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());
            }
       }
 }

当我替换以下Lambda表达式

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

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

它给了我编译错误。我正在使用java 8并通过eclipse进行编译。为什么会这样?为什么我不能将任意对象的实例方法的方法引用分配给消费者功能接口?

1 个答案:

答案 0 :(得分:6)

您对filterAgedPerson的定义需要Person作为参数,即使它不是静态方法。它并不需要,如果你想将它用作Consumer<Person>,它就不应该这样做。您最终得到的是与BiConsumer<Person, Person>兼容的内容。

以这种方式思考可能会有所帮助:对非静态方法的方法引用总是需要额外的&#34;额外的&#34;用作this的参数。

使用当前代码结构解决此问题的最简单方法是修改filterAgedPerson方法,不要将Person作为参数

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

另外,您可能还想考虑使用过滤器Predicate<Person>而不是Consumer<Person>,并将结果处理移到其他位置。随着事情变得更加复杂,这将为您提供更大的灵活性。