:: (double colon) operator in Java 8

前端 未结 17 2841
旧时难觅i
旧时难觅i 2020-11-21 11:10

I was exploring the Java 8 source and found this particular part of code very surprising:

//defined in IntPipeline.java
@Override
public fin         


        
17条回答
  •  后悔当初
    2020-11-21 11:44

    It seems its little late but here are my two cents. A lambda expression is used to create anonymous methods. It does nothing but call an existing method, but it is clearer to refer to the method directly by its name. And method reference enables us to do that using method-reference operator :: .

    Consider the following simple class where each employee has a name and grade.

    public class Employee {
        private String name;
        private String grade;
    
        public Employee(String name, String grade) {
            this.name = name;
            this.grade = grade;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getGrade() {
            return grade;
        }
    
        public void setGrade(String grade) {
            this.grade = grade;
        }
    }
    

    Suppose we have a list of employees returned by some method and we want to sort the employees by their grade. We know we can make use of anonymous class as:

        List employeeList = getDummyEmployees();
    
        // Using anonymous class
        employeeList.sort(new Comparator() {
               @Override
               public int compare(Employee e1, Employee e2) {
                   return e1.getGrade().compareTo(e2.getGrade());
               }
        });
    

    where getDummyEmployee() is some method as:

    private static List getDummyEmployees() {
            return Arrays.asList(new Employee("Carrie", "C"),
                    new Employee("Fanishwar", "F"),
                    new Employee("Brian", "B"),
                    new Employee("Donald", "D"),
                    new Employee("Adam", "A"),
                    new Employee("Evan", "E")
                    );
        }
    

    Now we know that Comparator is a Functional Interface. A Functional Interface is the one with exactly one abstract method (though it may contain one or more default or static methods). Lambda expression provides implementation of @FunctionalInterface so a functional interface can have only one abstract method. We can use lambda expression as:

    employeeList.sort((e1,e2) -> e1.getGrade().compareTo(e2.getGrade())); // lambda exp
    

    It seems all good but what if the class Employee also provides similar method:

    public class Employee {
        private String name;
        private String grade;
        // getter and setter
        public static int compareByGrade(Employee e1, Employee e2) {
            return e1.grade.compareTo(e2.grade);
        }
    }
    

    In this case using the method name itself will be more clear. Hence we can directly refer to method by using method reference as:

    employeeList.sort(Employee::compareByGrade); // method reference
    

    As per docs there are four kinds of method references:

    +----+-------------------------------------------------------+--------------------------------------+
    |    | Kind                                                  | Example                              |
    +----+-------------------------------------------------------+--------------------------------------+
    | 1  | Reference to a static method                          | ContainingClass::staticMethodName    |
    +----+-------------------------------------------------------+--------------------------------------+
    | 2  |Reference to an instance method of a particular object | containingObject::instanceMethodName | 
    +----+-------------------------------------------------------+--------------------------------------+
    | 3  | Reference to an instance method of an arbitrary object| ContainingType::methodName           |
    |    | of a particular type                                  |                                      |  
    +----+-------------------------------------------------------+--------------------------------------+
    | 4  |Reference to a constructor                             | ClassName::new                       |
    +------------------------------------------------------------+--------------------------------------+
    

提交回复
热议问题