🔶 Как начать в лямбда-выражения на Java
Пусть есть метод, который принимает набор данных и на основе какого-то условия возвращает новую выборку.
Допустим, нужно получить только четные числа из массива:
Если потребуется метод, который будет делать выборку чисел делящихся на пять, нужно будет писать ещё один метод с 99.9% повторяющегося кода
Если нужно получить выборку чисел, делящихся на 5 и на 11?
Don’t repeat yourself (DRY) – нет, не слышали...
Как обойти проблему дублирования кода?
1️⃣ описываем интерфейс с методом, принимающим число и возвращающим логическое значение:
1️⃣ описываем класс и делаем реализацию интерфейса:
Всё меняется если прописать это при помощи лямбда-выражения – не нужно описывать класс, а сразу указать так:
Дальше больше: можно не описывать отдельный интерфейс, потому что такой интерфейс уже есть в Java:
В Java есть и другие функциональные интерфейсы:
Удобно. Выгодно. Используем! Исходник на GitHub
#java #ооп
Пусть есть метод, который принимает набор данных и на основе какого-то условия возвращает новую выборку.
Допустим, нужно получить только четные числа из массива:
ArrayList<Integer> getItemsDividedBy2(int... numbers) {И ещё требуется найти числа, которые делятся на семь:
var result = new ArrayList<Integer>();
for (Integer item : numbers)
if (item % 2 == 0)
result.add(item);
return result;
}
ArrayList<Integer> getItemsDividedBy7(int... numbers) {Код точно такой же, но в первом случае у нас в метод "зашита" двойка, во втором – семёрка.
var result = new ArrayList<Integer>();
for (Integer item : numbers)
if (item % 7 == 0)
result.add(item);
return result;
}
Если потребуется метод, который будет делать выборку чисел делящихся на пять, нужно будет писать ещё один метод с 99.9% повторяющегося кода
Если нужно получить выборку чисел, делящихся на 5 и на 11?
Don’t repeat yourself (DRY) – нет, не слышали...
Как обойти проблему дублирования кода?
1️⃣ описываем интерфейс с методом, принимающим число и возвращающим логическое значение:
interface Divided {2️⃣ описываем метод, который принимает условие выборки и набор чисел:
boolean by(int value);
}
ArrayList<Integer> getItems(Divided divided, int... numbers) {Как использовать?
var result = new ArrayList<Integer>();
for (Integer item : numbers)
if (divided.by(item))
result.add(item);
return result;
}
1️⃣ описываем класс и делаем реализацию интерфейса:
class DividedBy2 implements Divided {2️⃣ Используем экземпляр класса DividedBy2 при вызове getItems
@Override
public boolean by(int value) {
return value % 2 == 0;
}
}
var n = getItems(new DividedBy2(), numbers);На первый взгляд выигрыша нет никакого, нужно описать интерфейс, потом класс с реализацией интерфейса.
Всё меняется если прописать это при помощи лямбда-выражения – не нужно описывать класс, а сразу указать так:
var n = getItems(e -> e % 3 == 0, numbers);Лямбда строится по принципу:
(параметры) -> (код метода).
Если аргумент один – скобки можно опустить.Дальше больше: можно не описывать отдельный интерфейс, потому что такой интерфейс уже есть в Java:
public interface Predicate<T>Т е нам нужно сразу при описании метода указать тип интерфейса и использовать его действие
test
:ArrayList<Integer> getItems(Predicate<Integer> divided, int... numbers) {
var result = new ArrayList<Integer>();
for (Integer item : numbers)
if (divided.test(item))
result.add(item);
return result;
}
а клиентский код var n = getItems(e -> e % 3 == 0, numbers);
остаётся прежним.В Java есть и другие функциональные интерфейсы:
Function<T,R>
,UnaryOperator<T>
,BinaryOperator<T>
,Consumer<T>
и т.д.Удобно. Выгодно. Используем! Исходник на GitHub
#java #ооп