Как лямбда-функция становится методом сравнения () Comparator? - PullRequest
0 голосов
/ 07 февраля 2019

Я видел, что в Java 8 можно определить компаратор следующим образом:

Comparator c = (Computer c1, Computer c2) -> c1.getAge().compareTo(c2.getAge());

, что эквивалентно:

Comparator d = new Comparator<Computer> () {
    @Override
    public int compare(Computer c1, Computer c2){
        return c1.getAge().compareTo(c2.getAge());
    }
};

Я хотел бы понять, как этоработает.Во втором примере это довольно просто: объект Comparator создается с помощью метода compare, который выполняет сравнение с использованием метода compareTo в свойстве age Computer.Этот метод просто вызывается нами, когда мы делаем:

Computer comp1 = new Computer(10);
Computer comp2 = new Computer(11);
d.compare(comp1, comp2); // -1

Но что происходит в первом примере, когда используется лямбда?Мне кажется, что мы устанавливаем Comparator равным методу, который выполняет сравнение.Но этого не может быть, потому что объект Comparator - это объект, у которого есть метод compare.Я узнал, что лямбды можно использовать с функциональными интерфейсами (интерфейсами только с одним методом).Но Comparator не является функциональным интерфейсом (у него есть много других методов, кроме compare!).Так как же интерпретатор Java узнает, что это реализуемый нами метод compare?

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

Технически, java.util.Comparator - это функциональный интерфейс, не только потому, что он аннотирован как единое целое, но и потому, что у него есть только один единственный (абстрактный) метод, compare(T, T).

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

См. Также Точное определение «функционального интерфейса» в Java 8

0 голосов
/ 07 февраля 2019

Пояснение

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

Он ведет себя очень похоже на другие методы создания экземпляров, такие как обычный класс, который расширяется, или анонимный класс.

Лямбда относится к одному методу, который требуется функциональному интерфейсу.Поскольку существует только один метод, он не является неоднозначным.Лямбда называет входные аргументы и затем дает реализацию для метода (он обеспечивает тело ).


Обзор

Выесть следующие опции для создания экземпляров интерфейсов или абстрактных классов:

  1. Создание расширяемого класса и использование нового
  2. Использование анонимного класса

Предполагается, что у нас есть интерфейс, который предлагает только один метод (он называется функциональный интерфейс тогда), у нас дополнительно есть следующие две опции для создания его экземпляров:

Использовать лямбда-выражение Использовать ссылку на метод

В качестве примера мы хотим создать экземпляр умножения, используя следующий интерфейс:

@FunctionalInterface
public interface Operation {
    int op(int a, int b);
}
  1. Создайте класс, который расширяется и используйте новый:

    public class Multiplicator implements Operation {
        @Override
        public int op(int a, int b) {
            return a * b;
        }
    }
    
    // Usage
    Operation operation = new Multiplicator();
    System.out.println(operation.op(5, 2)); // 10
    
  2. Используйте анонимный класс:

    Operation operation = new Operation() {
        @Override
        public int op(int a, int b) {
            return a * b;
        }
    };
    
    // Usage
    System.out.println(operation.op(5, 2)); // 10
    
  3. Используйте лямбда-выражение:

    Operation operation = (a, b) -> a * b;
    System.out.println(operation.op(5, 2)); // 10
    
  4. Используйте ссылку на метод:

    // Somewhere else in our project, in the `MathUtil` class
    public static int multiply(int a, int b) {
        return a * b;
    }
    
    // Usage
    Operation operation = MathUtil::multiply;
    System.out.println(operation.op(5, 2)); // 10
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...