Почему лямбда в C ++ никогда не DefaultConstructible

Кажется, его немного поздно, но вот мои два цента. Для создания анонимных методов используется выражение lambda . Он ничего не делает, кроме вызова существующего метода, но яснее ссылаюсь на метод непосредственно по его имени. И ссылка метода позволяет нам сделать это с помощью оператора ссылки на метод ::.

Рассмотрим следующий простой класс, в котором каждый сотрудник имеет имя и оценку.

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

Предположим, у нас есть список сотрудников, возвращаемых каким-то методом, и мы хотим сортировать сотрудников по их классу. Мы знаем, что мы можем использовать анонимный класс как:

    List employeeList = getDummyEmployees();

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

, где getDummyEmployee () - это некоторый метод как:

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

Теперь мы знаем что Comparator является функциональным интерфейсом. Функциональный интерфейс - это тот, который имеет только один абстрактный метод (хотя он может содержать один или несколько стандартных или статических методов). Поэтому мы можем использовать лямбда-выражение как:

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

Кажется, все хорошо, но что, если класс Employee также предоставляет аналогичный метод:

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

В этом случае, используя имя метода будет более понятным. Следовательно, мы можем напрямую ссылаться на метод, используя ссылку на метод:

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

В соответствии с docs существует четыре типа ссылок на методы:

+----+-------------------------------------------------------+--------------------------------------+
|    | 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                       |
+------------------------------------------------------------+--------------------------------------+

18
задан Community 23 May 2017 в 12:01
поделиться