Ссылки на методы в Java

Прежде чем мы перейдем к ссылкам на методы, я настоятельно рекомендую вам прочитать мою статью о лямбда-выражениях.

Что такое ссылки на методы?

Когда лямбда-выражение не делает ничего, кроме вызова существующего метода, часто понятнее использовать этот метод по имени. Ссылки на метод — это компактные, легко читаемые лямбда-выражения, у которых уже есть имя.

Рассмотрим этот класс Car:

public class Car{
  String modelName;
  int modelNum;
  LocalDate registrationDate;
  String vehicleNum;             

  public String getModelName(){..}

  public void printCar() {..}

  public static int compareByModelName(Car c1, Car c2){
    return c1.getModelName().compareTo(c2.getModelName());
  }
}
Войти в полноэкранный режим Выход из полноэкранного режима

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

public class CarModelNameCompartor implements Comparator<Car> {
  public static int compare(Car a, Car b) {
    return a.getModelName.compareTo(b.getModelName());
  }
}

Arrays.sort(cars, new CarModelNameComparator());
Вход в полноэкранный режим Выход из полноэкранного режима

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

Arrays.sort(cars, (a, b) -> 
  a.getModelName().compareTo(b.getModelName());
Ввести полноэкранный режим Выход из полноэкранного режима

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

Arrays.sort(cars, (a, b) -> Car.compareByModelName(a, b));
Ввести полноэкранный режим Выйти из полноэкранного режима

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

Arrays.sort(cars, Car::compareByModelName);
Войти в полноэкранный режим Выход из полноэкранного режима

Ссылки на методы и лямбда-выражения

Ссылки на метод семантически то же самое, что и метод, вызываемый внутри лямбда-выражения body (a, b) -> Car.compareByModelName(a, b).

  • Список параметров копируется из метода сравнения Comparator.
  • Его тело вызывает метод compareByModelName, передавая эти параметры.

Типы ссылок на методы

  • Статическая ссылка на метод
  • Ссылка на метод экземпляра
  • Ссылка на метод экземпляра произвольного объекта определенного типа
  • Ссылка на конструктор
public class MethodReferencesExample {
  public static <T> T merge(T a, T b, BiFunction<T,T,T> merger) {
    return merger.apply(a, b);
  }

  public static String appendStringsStaticMethod(String a, String b) {
    return a + b;
  }

  public String appendStringsInstanceMethod(String a, String b) {
    return a + b;
  }

  public static void main(String args[]) {
    String one = "Hello";
    String two = "World";

    // Referring a static method
    System.out.println(merge(one, two, MethodReferencesExample::appendStringsStaticMethod));

    //Referring an instance method
    MethodReferencesExample obj = new MethodReferencesExample();

    System.out.println(merge(one, two, obj::appendStringsInstanceMethod));

    //Referring an arbitrary object method of a particular type
    System.out.println(merge(one, two, String::concat));
  }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Во всех приведенных выше ссылках на метод будет сгенерирован один и тот же вывод HelloWorld.

Ссылка на конструктор

На конструктор можно ссылаться так же, как и на статический метод, например HashSet::new.

public static List<Car> getObjects(int length, Supplier<Car> supplier){
  List<Car> list = new ArrayList<Car>();

  for(int i = 0; i < length; i++){
    list.add(supplier.get());
  }

  return list;
}

List<Car> cars = getObjects(5, Car::new);
Вход в полноэкранный режим Выход из полноэкранного режима

Аналогичное лямбда-выражение для Car::new будет иметь вид

Заключение

Как было сказано выше, если лямбда-выражение вызывает только существующий метод, то использование ссылки на метод может сделать код более читабельным и понятным.

Спасибо, что прочитали блог. Не стесняйтесь вносить свои предложения и пожелания по улучшению кода. 🙂

Оцените статью
Procodings.ru
Добавить комментарий