Повестка дня:

  1. Понимание лямбда-выражений и их синтаксиса.
  2. Встроенные функциональные интерфейсы.

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

Начиная с версии 1.8 Java поддерживает лямбда-выражения. Java — это объектно-ориентированный язык программирования, однако лямбда добавляет в java некоторые функции функционального программирования.

В основном это возможность передать метод в качестве аргумента другому методу.

Начнем с примера

В приведенном выше фрагменте у нас есть класс Car со свойствами и класс TestDrive с одним методом testDrive. Основная идея этого метода заключается в вызове метода drive для разных моделей автомобилей. Сейчас тестируются только автомобили Tesla. Если нам нужно также протестировать разные модели, нам нужно либо изменить этот метод, передав аргумент для модели, либо создать новые методы для других моделей.

Мы пойдем с дополнительным аргументом

public void testDrive(List<Car> cars, String modelToTest) {        
    for (Car car : cars) {            
        if (car.model.equals(modelToTest)) {                
            car.drive();            
        }        
    }    
}

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

Для начала нам нужно определить функциональный интерфейс. Это интерфейс только с одним абстрактным методом. Затем этот интерфейс можно использовать в качестве аргумента для нашего метода testDrive, поэтому мы можем использовать синтаксис Lambda для передачи реализации для этого абстрактного метода.

  • Я определил наш интерфейс функции CarTester, где мы предоставили один абстрактный метод, который принимает объект Car и возвращает логическое значение.
  • Добавлен CarTester в качестве аргумента к методу testDrive и используется метод needToTest для CarTester, чтобы увидеть, какой автомобиль нужно проверить.
  • Использование лямбда-синтаксиса в основном методе, чтобы определить, на каком объекте автомобиля запускать метод привода.
// test Tesla and Audi models
testDrive.testDrive(cars, (Car e) -> {
    return e.model.equals("Tesla") || e.model.equals("Audi");
});

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

Разберем синтаксис анонимного метода.

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

// test white cars only
testDrive.testDrive(cars, (Car e) -> {
    return e.color.equals("white");
});

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

// test all white cars
testDrive.testDrive(cars, e -> e.color.equals("white"));

Приведенный выше фрагмент также является допустимым способом передачи анонимного метода.

Встроенные функциональные интерфейсы

В Java есть много встроенных функциональных интерфейсов, поэтому нам не нужно создавать интерфейсы для часто используемых функций.

как мы их используем?

Давайте перепишем приведенный выше пример, используя Predicate

  • Я удалил свой собственный интерфейс и просто использовал Predicate
  • Остальной код такой же, и он работает так, как ожидалось.

Давайте посмотрим на несколько примеров, где java использует эти встроенные функциональные интерфейсы.

Please take my Java Course for video lectures.
This article is part of the series of articles to learn Java programming language from Tech Lead Academy:
Introduction to programming 
OS, File, and File System
Working with terminal 
Welcome to Java Programming Language
Variables and Primitives in Java
Convert String to numeric data type
Input from the terminal in Java
Methods with Java
Java Math Operators and special operators
Conditional branching in Java
Switch statement in Java
Ternary operator in Java
Enum in Java
String class and its methods in Java
Loops in Java
Access modifiers in Java
Static keyword in Java
The final keyword in Java
Class and Object in Java
Object-Oriented Programming in Java
OOP: Encapsulation in Java
OOP: Inheritance in Java
OOP: Abstraction in Java
OOP: Polymorphism in Java
The method Overriding vs Overloading in Java
Array in Java
Data Structures with Java
Collection framework in Java
ArrayList in Java
Set in Java
Map in Java
Date and Time in Java
Exception in Java
How to work with files in Java
Design Patterns
Generics in Java
Multithreading in java
Annotations in Java
Reflection in Java
Reflection & Annotations - The Powerful Combination
Run terminal commands from Java
Lambda in Java
Unit Testing in Java
Big O Notation for coding interviews
Top Java coding interview questions for SDET