Java 8. Лямбда выражения
JDK 1.8 содержит в себе самые большие изменения со времен Java 5. Пожалуй, самое неоднозначное новшество — это поддержка лямбда выражений и функционального программирования. На многих форумах Java программисты устраивают настоящие баталии, поднимая вопрос: «Есть ли место функциональному программированию в ООП?». Ну, а пока кто-то спорит о правильности внедрения новых возможностей в JDK, мы разберемся с тем, что это такое Lambda Expressions, и с чем его едят.
Для начала, рассмотрим пример создания нового потока
Thread
при помощи реализации анонимного класса Runnable
:
1
2
3
4
5
6
7
| Thread threadWithoutLambdas = new Thread( new Runnable() { @Override public void run() { System.out.println( "Runnable anonymous class in Thread." ); } }); threadWithoutLambdas.start(); |
Output: Runnable anonymous class in Thread.
А теперь попробуем заменить анонимный класс лямбда выражением:
1
2
| Thread threadWithLambdas = new Thread(() -> System.out.println( "Lambda Expressions in Thread." )); threadWithLambdas.start(); |
Output: Lambda Expressions in Thread.
Что же мы видим из этого примера, кроме того, что у нас упростился синтаксис создания потока и стало меньше строчек кода? Из этого примера видно, что Java компилятор уже вместо разработчика подставляет реализацию в интерфейс
Runnable
, который имеет всего один метод run()
. Из-за более упрощенного синтаксиса у нас улучшается читаемость, так как после создания класса Thread
следует непосредственно та часть кода, которая отвечает за работу потока. Ничего лишнего.Структура лямбда выражений
Наше лямбда выражение имеет следующую структуру:
1
| (method params) -> {lambda expression body} |
Оператор
->
служит разделителем между списком параметров нашего метода и телом, в котором происходит его реализация. Более детальное пояснение представлено в следующих примерах:x -> x + 1;
— Такая реализация допустима, когда метод принимает в качестве параметра и возвращает значение типа x. Если параметр всего один, то круглые скобки( )
не обязательны, так же не обязательно использовать операторreturn
и оборачивать тело выражения в фигурные скобки{ }
, если выполняется всего одна операция.(x, y) -> {System.out.println(x + y); return 0;}
— Тут представлен совершенно противоположный случай, когда наше выражение принимает 2 параметра —x
иy
, а тело, не просто возвращает результат, но и выполняет промежуточную операцию, в нашем случае — выводит на консоль значение ноль (Так сказать, код успешного выполнения операции).() -> System.out.println("Hello my Friend!");
— Могут встречаться и такие конструкции. Так как не всегда метод, который выполняет какую-то операцию, должен принимать либо возвращать значения.
Ссылки на метод
Основная идея состоит в том, чтобы избавить разработчика от ненужного и громоздкого создания объектов и вызова его методов внутри тела лямбда выражений. Вместо этого вам предоставляется возможность просто указать метод, который вы собираетесь вызвать, ссылаясь на сам класс, а не на его экземпляр, при помощи оператора
::
. Стандартная форма записи выглядет следующим образом: Class::method
. Как вы могли догадаться: Class
— это имя класса, а method
— метод, на который вы собираетесь сослаться. Обратите внимание на то, что программисту уже не нужно беспокоиться о списке параметров и значениях, которые нужно передать методу, теперь всю заботу об этом на себя принимает лямбда выражение.
Рассмотрим несколько примеров, которые помогут нам разобраться, когда же все таки стоит использовать ссылку на метод, вместо того, чтоб обращаться к методу через экземпляр класса.
Вызов метода через экземпляр класса | Вызов метода по ссылке |
---|---|
a -> System.out.print(a); | System.out::print; |
() -> new StringBuilder(); | StringBuilder::new; |
No comments:
Post a Comment