Друзья, всем привет.
Сегодняшняя статья будет короткой, в ней мы поговорим о функциональном интерфейсе UnaryOperator<T>, доступном в Java, начиная с версии 1.8.
Этот функциональный интерфейс является наследником интерфейса Function<T, R>, который мы уже разбирали ранее в рамках отдельной статьи.
Интерфейс описывает некоторый унарный оператор, т.е. оператор, работающий лишь с одним операндом и возвращающий результат выполнения оператора с тем же самым типом, как и у операнда.
К распространённым унарным операторам относятся, например, операции инкремента (++) и декремента (--):
int i = 0;
i++; // оператор инкремента, результат его выполнения - значение локальной переменной i будет увеличино на единицу
System.out.println("i = " + i); // вывод в консоль: i = 1
int j = 10;
j--; // оператор декремента, результат его выполнения - значение локальной переменной j будет уменьшено на единицу
System.out.println("j = " + j); // вывод в консоль: j = 9
У интерфейса UnaryOperator<T> есть единственный параметр типа - T, который задаёт тип входного аргумента и одновременно тип результата самой унарной операции.
Его удобно применять в программах, когда требуется некоторое преобразование входного значения заданного типа, при этом результат преобразования также имеет этот же самый тип, что и сам аргумент операции.
Рассмотрим небольшой пример программы на Java для демонстрации работы с функциональным интерфейсом UnaryOperator<T>:
package ru.allineed.samples.functional_interface.unaryoperator;
import ru.allineed.samples.common.OutputUtils;
import java.util.Arrays;
import java.util.List;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
public class UnaryOperatorExample {
public static void main(String[] args) {
OutputUtils.printSampleTitle(
"Функциональный интерфейс UnaryOperator в Java",
"Functional interface UnaryOperator in Java",
"https://allineed.ru/development/java-development/TODO");
showIntegerIncrementDemo();
showGreeterDemo();
}
private static void showGreeterDemo() {
UnaryOperator<String> greeter = e -> "Привет, " + e + "!";
List<String> people = Arrays.asList("Александр", "Иван", "Пётр", "Михаил");
System.out.println(people.stream().map(greeter).collect(Collectors.toList()));
}
private static void showIntegerIncrementDemo() {
UnaryOperator<Integer> increment = e -> e + 1;
List<Integer> numbers = Arrays.asList(2, 3, -5);
System.out.println(increment.apply(3));
// [RU] Использование интерфейса UnaryOperator в виде готовой переменной 'increment' внутри метода Stream#map
// [EN] Using UnaryOperator interface as a predefined variable 'increment' inside method Stream#map
System.out.println(numbers.stream().map(increment).collect(Collectors.toList()));
// [RU] Использование интерфейса UnaryOperator в виде лямбда-выражения внутри метода Stream#map
// [EN] Using UnaryOperator interface as lambda expression inside method Stream#map
System.out.println(numbers.stream().map(e -> e + 1).collect(Collectors.toList()));
}
}
Как видим, в главном методе main() нашего примера мы вызываем два отдельных метода:
- showIntegerIncrementDemo - демонстрирует работу унарного оператора, реализующего операцию инкремента с целыми числами
- showGreeterDemo - демонстрирует работу унарного оператора на строках - оператор добавляет приветствие для переданного ему аргумента
В методе showIntegerIncrementDemo мы создаём переменную increment и присваиваем ей лямбда-выражение, которое будет брать входной аргумент для унарной операции (e), прибавлять к нему единицу (e + 1) и возвращать полученный результат:
UnaryOperator<Integer> increment = e -> e + 1;
Далее мы создаём список numbers из трёх целых чисел:
List<Integer> numbers = Arrays.asList(2, 3, -5);
Следующей строкой мы применяем наш унарный оператор для инкремента к числу 3:
System.out.println(increment.apply(3));
Далее показано, как можно использовать унарный оператор при работе со стримами:
System.out.println(numbers.stream().map(increment).collect(Collectors.toList()));
System.out.println(numbers.stream().map(e -> e + 1).collect(Collectors.toList()));
В обоих случаях мы пробегаем по входному списку numbers и для каждого его элемента применим унарный оператор инкремента, а результирующий список вернем в отдельную коллекцию.
В случае метода showGreeterDemo мы создаём простой унарный оператор, который добавляет приветствие к переданному ему строковому аргументу (мы предполагаем здесь, что это всегда будет чьё-то имя):
UnaryOperator<String> greeter = e -> "Привет, " + e + "!";
Дальше мы создаём список из имён и "приветствуем" каждого человека из списка, указывая наш унарный оператор в методе Stream#map:
List<String> people = Arrays.asList("Александр", "Иван", "Пётр", "Михаил");
System.out.println(people.stream().map(greeter).collect(Collectors.toList()));
Запустим наш класс UnaryOperatorExample и посмотрим, что будет выведено на консоль:
========================================================================================================================
>> Запуск примера для статьи "Функциональный интерфейс UnaryOperator в Java"
>> Ссылка на статью: https://allineed.ru/development/java-development/84-java-unaryoperator
========================================================================================================================
4
[3, 4, -4]
[3, 4, -4]
[Привет, Александр!, Привет, Иван!, Привет, Пётр!, Привет, Михаил!]
Мы видим, что число 3 было инкрементировано и на экран вывелся результат: 4
Далее мы видим две строки, где входной массив чисел numbers также был инкрементирован, и каждое число было увеличено на единицу.
Наконец, в конце вывода консоли отображён список, где мы приветствуем каждого человека из списка people.
Итак, мы кратко познакомились с тем, как работает функциональный интерфейс UnaryOperator<T> в Java, а также посмотрели на варианты его применения в стримах Java.
В завершение статьи отмечу, что его также можно использовать и с любыми другими доступными типами Java (не только String и Integer, как в нашем примере), включая ваши собственные классы и типы, которые вы зададите в вашей программе.
Ссылку на наш Git-репозиторий и пример кода из данной статьи, а также инструкцию по запуску примеров вы найдете внизу.
Спасибо за внимание и удачи!
Примеры из этой статьи: https://github.com/AllineedRu/JavaExamples/blob/main/allineed-core/src/main/java/ru/allineed/samples/functional_interface/unaryoperator/UnaryOperatorExample.java