← Назад к вопросам

Что такое лямбда-выражения в Java? Приведите примеры использования.

2.0 Middle🔥 221 комментариев
#Stream API и функциональное программирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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

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

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

Базовый синтаксис

(параметры) -> { тело функции }

Примеры синтаксиса

// Без параметров
() -> System.out.println("Hello");

// С одним параметром (скобки опциональны)
x -> x * 2
(x) -> x * 2

// С несколькими параметрами
(x, y) -> x + y

// С телом из нескольких строк
(x) -> {
    int result = x * 2;
    System.out.println("Result: " + result);
    return result;
}

1. Использование с функциональными интерфейсами

Лямбда-выражения работают с функциональными интерфейсами (интерфейсы с одним абстрактным методом):

// Функциональный интерфейс
@FunctionalInterface
public interface Calculator {
    int calculate(int a, int b);
}

// Использование лямбда-выражения
Calculator add = (a, b) -> a + b;
Calculator multiply = (a, b) -> a * b;

System.out.println(add.calculate(5, 3));      // 8
System.out.println(multiply.calculate(5, 3)); // 15

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

Predicate<T> — условие

import java.util.function.Predicate;

Predicate<Integer> isPositive = n -> n > 0;
Predicate<String> isLonger = s -> s.length() > 5;

System.out.println(isPositive.test(5));      // true
System.out.println(isPositive.test(-5));     // false
System.out.println(isLonger.test("Hello"));  // false
System.out.println(isLonger.test("Hello, World!")); // true

Function<T, R> — преобразование

import java.util.function.Function;

Function<Integer, Integer> square = n -> n * n;
Function<String, Integer> stringToLength = s -> s.length();

System.out.println(square.apply(5));              // 25
System.out.println(stringToLength.apply("Hello")); // 5

Consumer<T> — действие

import java.util.function.Consumer;

Consumer<String> print = s -> System.out.println(s);
Consumer<Integer> addToList = n -> numbers.add(n);

print.accept("Hello");   // Hello
addToList.accept(42);    // добавляет 42 в список

Supplier<T> — поставщик

import java.util.function.Supplier;

Supplier<String> getGreeting = () -> "Hello, World!";
Supplier<Integer> randomNumber = () -> new Random().nextInt(100);

System.out.println(getGreeting.get());  // Hello, World!
System.out.println(randomNumber.get()); // случайное число

3. Использование с Collections

Filter с Predicate

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

// Фильтруем чётные числа
List<Integer> evenNumbers = numbers.stream()
    .filter(n -> n % 2 == 0)
    .collect(Collectors.toList());

System.out.println(evenNumbers); // [2, 4, 6, 8, 10]

Map с Function

List<String> words = Arrays.asList("Hello", "World", "Java");

// Преобразуем в длины слов
List<Integer> lengths = words.stream()
    .map(s -> s.length())
    .collect(Collectors.toList());

System.out.println(lengths); // [5, 5, 4]

ForEach с Consumer

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

// Выводим каждое имя
names.forEach(name -> System.out.println("Hello, " + name));

// Результат:
// Hello, Alice
// Hello, Bob
// Hello, Charlie

4. Лямбда в методах Java 8+

sorted() с Comparator

List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6);

// Сортируем по возрастанию
numbers.sort((a, b) -> Integer.compare(a, b));
System.out.println(numbers); // [1, 1, 2, 3, 4, 5, 6, 9]

// Сортируем по убыванию
numbers.sort((a, b) -> Integer.compare(b, a));
System.out.println(numbers); // [9, 6, 5, 4, 3, 2, 1, 1]

reduce() — агрегация

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

// Сумма всех элементов
int sum = numbers.stream()
    .reduce(0, (a, b) -> a + b);
System.out.println(sum); // 15

// Произведение всех элементов
int product = numbers.stream()
    .reduce(1, (a, b) -> a * b);
System.out.println(product); // 120

5. Практические примеры

Валидация данных

@FunctionalInterface
public interface Validator<T> {
    boolean validate(T value);
}

public class UserValidator {
    private static final Validator<String> emailValidator = 
        email -> email != null && email.contains("@");
    
    private static final Validator<Integer> ageValidator = 
        age -> age >= 18 && age <= 120;
    
    public static void main(String[] args) {
        System.out.println(emailValidator.validate("user@example.com")); // true
        System.out.println(emailValidator.validate("invalid"));          // false
        System.out.println(ageValidator.validate(25));                   // true
        System.out.println(ageValidator.validate(15));                   // false
    }
}

Конфигурирование обработчиков событий

@Service
public class EventService {
    
    private List<Consumer<String>> eventHandlers = new ArrayList<>();
    
    public void subscribe(Consumer<String> handler) {
        eventHandlers.add(handler);
    }
    
    public void emit(String event) {
        eventHandlers.forEach(handler -> handler.accept(event));
    }
}

// Использование
EventService events = new EventService();
events.subscribe(msg -> System.out.println("Handler 1: " + msg));
events.subscribe(msg -> System.out.println("Handler 2: " + msg));
events.emit("User logged in");

// Результат:
// Handler 1: User logged in
// Handler 2: User logged in

Фильтрация и трансформация объектов

public class User {
    private String name;
    private int age;
    private String email;
    
    // getters...
}

List<User> users = Arrays.asList(
    new User("Alice", 25, "alice@example.com"),
    new User("Bob", 17, "bob@example.com"),
    new User("Charlie", 30, "charlie@example.com")
);

// Найти всех совершеннолетних пользователей
List<User> adults = users.stream()
    .filter(user -> user.getAge() >= 18)
    .collect(Collectors.toList());

// Получить email адреса совершеннолетних
List<String> adultEmails = users.stream()
    .filter(user -> user.getAge() >= 18)
    .map(User::getEmail)
    .collect(Collectors.toList());

6. Ссылки на методы (Method References)

Лямбда-выражения можно заменить ссылками на методы для улучшения читаемости:

List<String> words = Arrays.asList("Hello", "World");

// Вместо:
words.forEach(word -> System.out.println(word));

// Используй ссылку на метод:
words.forEach(System.out::println);

// Другие примеры:
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5);
numbers.sort(Integer::compare);              // вместо (a, b) -> a.compare(b)
List<String> upper = words.stream()
    .map(String::toUpperCase)                // вместо s -> s.toUpperCase()
    .collect(Collectors.toList());

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

  1. Компактность — меньше кода, чем анонимные классы
  2. Читаемость — код становится более выразительным
  3. Функциональный стиль — поддержка функционального программирования
  4. Параллелизм — удобно использовать с parallel streams
  5. Производительность — часто быстрее, чем анонимные классы

Резюме

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

  • Позволяют передавать блоки кода как аргументы методам
  • Работают с функциональными интерфейсами
  • Делают код компактнее и читабельнее
  • Поддерживают функциональное программирование
  • Работают отлично с Stream API
Что такое лямбда-выражения в Java? Приведите примеры использования. | PrepBro