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
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. Why is this so? Why cannot I assign method reference for instance method of any arbitrary object to consumer functional interface?
Java Consumer Interface It is a functional interface defined in java.util.function package. It contains an abstract accept () and a default andThen () method. It can be used as the assignment target for a lambda expression or method reference.
Method references are simple, easy-to-read lambda expressions to call/refer and existing method by name in a lambda expression. Following is the syntax to reference a instance method in Java
The following is an example of a reference to an instance method of a particular object: The method reference myComparisonProvider::compareByName invokes the method compareByName that is part of the object myComparisonProvider. The JRE infers the method type arguments, which in this case are (Person, Person).
A method is a function written inside the class. Since java is an object-oriented programming language, we need to write a method inside some classes. Instance methods can access instance variables and instance methods directly and undeviatingly. Instance methods can access static variables and static methods directly.
Your definition of filterAgedPerson
takes a Person
as an argument, even though it is not a static method. It doesn't need to, and it shouldn't if you want to use it as a Consumer<Person>
. What you are ending up with is something compatible with 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
.
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
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. This will give you more flexibility as things get more complicated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With