-3

I am using predicates supported in Java 8, in which I am using lambdas, but I want to use method references in place of lambdas. Please advise how to achieve this. Below is my code.

public class Employee {

   public Employee(Integer id, Integer age, String gender, String fName, String lName){
       this.id = id;
       this.age = age;
       this.gender = gender;
       this.firstName = fName;
       this.lastName = lName;
   }

   private Integer id;
   private Integer age;
   private String gender;
   private String firstName;
   private String lastName;

   //Please generate Getter and Setters

    @Override
    public String toString() {
        return this.id.toString()+" - "+this.age.toString(); //To change body of generated methods, choose Tools | Templates.
    }

And here I am using predicates with lambdas where I want to remove lambdas and use method references instead:

public class EmployeePredicates
{
    public static Predicate<Employee> isAdultMale() {
        return p -> p.getAge() > 21 && p.getGender().equalsIgnoreCase("M");
    }

    public static Predicate<Employee> isAdultFemale() {
        return p -> p.getAge() > 18 && p.getGender().equalsIgnoreCase("F");
    }

    public static Predicate<Employee> isAgeMoreThan(Integer age) {
        return p -> p.getAge() > age;
    }

    public static List<Employee> filterEmployees (List<Employee> employees, Predicate<Employee> predicate) {
        return employees.stream().filter( predicate ).collect(Collectors.<Employee>toList());
    }
}  
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
user1620642
  • 79
  • 10
  • 3
    Well if you don't have a method that does what you want to do, how do you expect to use a method reference? It's unclear what you're trying to achieve - or why. – Jon Skeet Oct 14 '17 at 16:17
  • @Jon Skeet please advise how can i use method references in place of lambdas – user1620642 Oct 14 '17 at 16:19
  • 2
    You can only replace a lambda with a method reference if the body of the lambda does nothing more than call a single method. Your predicates do not apply because they have other things e.g. >. If you are using a good IDE (e.g. IntelliJ) it will tell you when a lambda can be replaced by a method reference. I'd worry about it when it happens. – cpp beginner Oct 14 '17 at 16:24
  • @cppbeginner is this is also possible in eclipse also – user1620642 Oct 14 '17 at 16:28
  • @user1620642 You can also do it in eclipse(ctrl+1 on lambda sign). – Chota Bheem Oct 14 '17 at 19:26

1 Answers1

2

I needed to rewrite your snippet with the "method reference syntax" to show you all the weirdness and incorrectness of their usage here. Please, don't do this!

public static Predicate<Employee> isAdultMale() {
    return e -> ((Predicate<Employee>)EmployeePredicates::isAgeMoreThan21).test(e) && ((Predicate<Employee>)EmployeePredicates::isMale).test(e);
}

private static boolean isAgeMoreThan21(Employee employee) {
    return employee.getAge() > 21;
}

private static boolean isMale(Employee employee) {
    return employee.getGender().equalsIgnoreCase("M");
}

Method references can't normally be used in logical expressions (like methodReference1 && methodReference2) and the expressions that need some extra information (like the method isAgeMoreThan(age) - that's why I had to transform it into the method isAgeMoreThan21()).

As it was suggested by @tobias_k, standard logical operators could be replaced with corresponding methods of the Predicate to combine instances of this type:

public static Predicate<Employee> isAdultMale() {
    return ((Predicate <Employee>)EmployeePredicates::isAgeMoreThan21).and(EmployeePredicates::isMale);
}
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
  • 1
    While I generally agree, you could also use the slightly less horrible `return ((Predicate ) EmployeePredicates ::isAgeMoreThan21) .and(EmployeePredicates ::isMale);` – tobias_k Oct 14 '17 at 17:01