Перейти к содержимому

Что такое лямбда в программировании

  • автор:

Лямбда-выражения в Java — что это такое, зачем нужны и как выглядят

Лямбда-выражения или анонимные функции встречаются во многих языках программирования. Рассказываем про лямбда-выражения в Java с примерами.

Лямбда-выражения встречаются в разных языках программирования: JavaScript, PHP, C# и других. В этой статье поговорим о лямбда-выражениях в Java.

Лямбда-выражения или анонимные функции — это блоки кода с параметрами, которые можно вызвать из другого места программы. Они называются анонимными, потому что в отличие от функций, у них нет имён. Слово «лямбда» пришло из лямбда-исчисления, которое придумал профессор Алонзо Чёрч. Он использовал греческую букву лямбда (λ), чтобы отметить параметры.

Лямбда-выражения в Java

  • Присутствуют начиная с 8 версии.
  • Являются анонимными классами, реализующими метод функционального интерфейса.
  • Имеют доступ только к final (или effectively final) переменным из охватывающей области видимости (для потокобезопасности).
  • Не могут возвращать значение в каких-то ветках, а в других не возвращать.
  • Позволяют уменьшить количество кода и повысить его читаемость.

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

Лямбда-выражения в Java состоят из параметров и стрелки —> отделяющей тело функции. Скобки нужны, если параметров 0 или больше одного. Для однострочных лямбд ключевое слово return не обязательно.

(список параметров) -> тело лямбды

Без параметров

@FunctionalInterface interface MyFunctionalInterface < //метод без параметров public String sayHello(); >public class Example < public static void main(String args[]) < // лямбда выражение MyFunctionalInterface msg = () ->< return "Привет мир"; >; System.out.println(msg.sayHello()); > > 

Этот код выведет в консоль текст: «Привет мир!».

C параметром

import java.awt.*; public class ButtonListenerNewWay < public static void main(String[] args) < Frame frame=new Frame("ActionListener java8"); Button b=new Button("Click Here"); b.setBounds(50,100,80,50); b.addActionListener(e ->System.out.println("Привет мир!")); frame.add(b); frame.setSize(200,200); frame.setLayout(null); frame.setVisible(true); > > 

В этом примере лямбда-выражение используется для обработки нажатия кнопки.

С несколькими параметрами

interface StringConcat < public String sconcat(String a, String b); >public class Example < public static void main(String args[]) < StringConcat s = (str1, str2) ->str1 + str2; System.out.println("Result: "+s.sconcat("Hello ", "World")); > > 

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

Что такое лямбда-функции в программировании

Функции в языках программирования — это такие небольшие автономные программы, которые работают внутри основного кода. При запуске они могут взять какие-то стартовые параметры, обработать их, получить свой результат и отдать этот результат в основной код.

Чтобы вызвать функцию, нужно указать её имя, но бывают такие функции, у которых нет имени, но их всё равно можно вызывать. Рассказываем, как это работает.

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

Как работает обычная функция

Классическая функция выглядит так:

  1. Имя функции.
  2. Тело функции.
  3. Может быть: результат, который она возвращает, но может и не возвращать.

Запишем это на Python, чтобы было наглядно:

def add(x, y): result = x + y return result print(add(2,3))

У этой функции есть имя add . Есть то, что она делает внутри: складывает два числа. И есть результат, который она возвращает, — он хранится в переменной result . Чтобы вызвать эту функцию, мы указываем её имя и аргументы, которые ей нужно обработать: print(add(2,3)) .

Сейчас функция кажется избыточной, мол, сложение чисел можно сделать и так. Но саму эту функцию внутри можно сделать намного сложнее. Например, что могла бы делать эта функция:

  • Проверять, какие данные ей подали на вход, и в зависимости от их типа складывать их по-разному. Например, если ей дадут две строки, она может выдать ошибку; а может соединить строки.
  • Складывать не числа, а массивы из чисел. Правила сложения массивов нужно будет прописать.
  • Вести учёт всех сложений, которые она делала.
  • Преобразовывать входящие или исходящие данные.
  • Возвращать данные не в виде числа, а в виде целого объекта с кучей свойств, если это нужно программе.

И это только банальное сложение. Всю эту логику удобно упаковать внутрь функции и вызывать с помощью простого слова add() .

Что такое лямбда-функция

Лямбда-функция выглядит иначе: у неё нет имени, но есть ключевое слово lambda — оно показывает, что дальше пойдёт безымянная функция. В общем виде лямбда-функция выглядит так:

lambda переменные: значение функции

Чтобы эта функция могла куда-то вернуть своё значение, лямбда-функции присваивают переменным — и после этого их можно использовать как обычные функции. Перепишем наш пример со сложением в виде лямбда-функции:

result = lambda x, y: x + y print(result(2,3))

Если мы запустим оба фрагмента кода, то в обоих случаях увидим на экране число 5.

Может показаться, что во втором случае у нас всё равно получилась функция result, просто записанная иначе, и нет никакой разницы с первым способом. Но на самом деле различия есть: обычные функции не получится использовать на месте переменных, а лямбда-функции — можно. Про это расскажем чуть ниже.

Ограничение лямбда-функций

Значение лямбда-функции в Python должно быть записано в одну строку. Это значит, что внутри лямбда-функций не может быть циклов, других функций и всего остального, что требует для записи нескольких строк.

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

Также в лямбдах нет присваивания — это простое выражение, которому не нужно ничего промежуточно хранить, а нужно лишь посчитать.

Откуда такое название

Название лямбда-функций пришло в программирование из математического λ-исчисления, где λ — это как раз греческая буква «лямбда». Смысл там в том, что всё построено на переменных и их взаимодействии друг с другом. Условно, чтобы посчитать одно выражение, нужно найти значение всех его значений, тоже выраженное каким-то формулами, а потом подставить нужный параметр вместо переменной.

В лямбда-функциях всё то же самое:

  • есть выражение, заданное с помощью переменных;
  • есть общее значение, которое зависит от этого выражения;
  • когда мы подставляем в лямбда-функцию какое-то значение, функция обрабатывает его и получает определённый результат;
  • этот результат будет влиять на итог общего значения.

Зачем нужны лямбда-функции

Самая популярная область применения лямбда-функций — в качестве аргументов в других функциях. Мы с этим ещё столкнёмся в новых проектах, а пока пара примеров.

Допустим, у нас есть список с числами, из которого нам нужно отобрать только чётные. Для этого можно писать классическую функцию, которая переберёт каждый элемент списка и, если он чётный, добавит его в итоговый результат. А можно использовать лямбду и встроить фильтр сразу в момент создания нового списка:

lst = [1, 2, 3, 4, 5, 6, 7, 8, 9] new_lst = list(filter(lambda x: (x%2 == 0) , lst)) print(new_lst)

Смотрите, что тут произошло:

  1. Мы сделали список с разными числами.
  2. Потом мы создали новый на основе старого, используя команду filter() — она выбирает из списка нужные элементы по критерию.
  3. В качестве такого критерия мы указали, что элемент можно брать, только если он чётный.
  4. Значения этих элементов берутся из старого списка lst.

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

Вот пример посложнее, но нагляднее: вывести словарь в порядке убывания суммы каждого значения. Алгоритму нужно сначала найти сумму значений каждого элемента словаря, отсортировать их по убыванию, а потом запомнить новый порядок вывода. Для этого используют функцию sorted() — она сортирует словарь по определённому критерию, но вот сам критерий проще всего определить с лямбдой:

bigrams = sorter = sorted(bigrams, key=lambda key: sum(bigrams[key]), reverse=True) for key in sorter: print(key, bigrams[key])

Здесь key — это как раз критерий фильтра, в котором мы используем лямбда-функцию. Эта функция считает сумму значений каждого элемента словаря и превращает это в критерий сортировки. Функции остаётся только быстро пробежать по всему словарю, используя готовые суммы, и отсортировать его в обратном направлении:

Что такое лямбда-функции в программировании

А вот если бы мы сделали это в виде обычной функции, получилось бы сложнее и не так очевидно. Сравните этот код с предыдущим — он делает то же самое, но выглядит более громоздко:

from functools import partial def sort_func(key, dict): return sum(dict[key]) bigrams = partial_sort = partial(sort_func, dict=bigrams) sorter = sorted(bigrams.keys(), key=partial_sort, reverse=True) for key in sorter: print(key, bigrams[key])

Ещё лямбда-функции иногда используют для создания замыканий — функций внутри функций, которые тоже зависят от входных параметров:

def addition(x): return lambda y: x + y add_to_ten = addition(10) print(add_to_ten(8)) print(add_to_ten(6))

Получается, что технически можно обойтись и без лямбда-функций, но с ними иногда получается удобнее. Это узкоспециализированный инструмент, который не нужен в каждом коде, но с ним некоторые вещи становятся гораздо проще.

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

@niki-timofe, это слабое оправдание. Если вы не приложите усилий, чтобы задать хороший вопрос, то не можете ожидать, что мы приложим усилия, чтобы дать хороший ответ. Таким образом вам придется удовлетвориться копипастой из ссылки выше, что несколько глупо для программиста, ибо подразумевает выполнение машинной работы вручную.

19 мая 2012 в 20:23

4 ответа 4

Сортировка: Сброс на вариант по умолчанию

Лямбда-функции — это функции, у которой фактически нет имени. Таким образом математики упростили до невозможности формат записи функции, а вообще лямбда-исчислениями пытались формализовать вычисления

λ — означает, что это лямбда-функция. Всё что после неё — список аргументов, в идеале абсолютно любого типа, в том числе может быть и другая лямбда-функция. После точки идёт «тело функции», а уже потом, собственно, идёт аргумент, который будет передан. Т.о.

λx.x+2 2 // вернёт 4 
λx.x 2 λy.y+1 // результат 3 

Здесь в качестве параметра x выступает другая лямбда-функция λy.y + 1 , в которую передаётся параметр 2. То есть любая лямбда функция является функцией высшего порядка, может принимать в качестве аргумента другую функцию и возвращать функцию:

λx.λy.y+x+3 2 // вернёт λy.y+5, т.к. x был равен двум. λx.λy.y+x+3 2 3 // вернёт 8. Фактически это каррирование: сначала функция принимает аргумент 2 и возвращает функцию, которая принимает ещё один аргумент и возвращает результат. 

Если интересно, я когда-то писал аналогичные вещи на C#

Теперь давайте посмотрим, как же все наши примеры будут выглядеть на C#. Здесь в качестве лямбда-функции я использую Func, где T — тип аргумента, а U — тип возвращаемого значения:

1) Func func = x=>x; 2) var result = new Func(x=>x+2)(2); 3) var result = new Func(x=>x(2))(new Func(y=>y+1)); 4) var result = new Func(x=>y=>y+x+3)(2); 5) var result = new Func(x=>y=>y+x+3)(2)(3); 

Сложность составляет только явное указание типа аргументов и возвращаемого значения.

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

Ознакомьтесь с мощными и гибкими лямбда-выражениями в Java, которые упрощают код и делают его более читабельным!

Алексей Кодов
Автор статьи
9 июня 2023 в 16:31

Лямбда-выражения являются важным нововведением в Java, начиная с версии Java 8. Они представляют собой сокращенный синтаксис для представления объектов, реализующих функциональные интерфейсы, и позволяют писать более компактный и выразительный код.

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

Функциональный интерфейс — это интерфейс с одним абстрактным методом. Java 8 включает также механизм default методов, которые позволяют добавлять реализацию методов в интерфейсы, но функциональный интерфейс должен содержать только один абстрактный метод. Пример функционального интерфейса:

@FunctionalInterface public interface MyFunction
Java-разработчик: новая работа через 11 месяцев
Получится, даже если у вас нет опыта в IT

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

Лямбда-выражение представляет собой анонимную функцию, которую можно передать в качестве аргумента или присвоить переменной. Синтаксис лямбда-выражений включает в себя параметры, стрелку -> и тело выражения. Пример использования лямбда-выражения:

MyFunction square = x -> x * x; int result = square.apply(4); // Результат: 16

Преимущества лямбда-выражений

Лямбда-выражения упрощают написание кода и делают его более читабельным. Например, они могут использоваться с методами высшего порядка, такими как filter , map и reduce , для обработки коллекций данных без необходимости писать многословные анонимные классы.

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); List<Integer> evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(Collectors.toList());

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

Заключение

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *