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

Что такое интерфейс Consumer?

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

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

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

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

Интерфейс Consumer в Java

Consumer — это функциональный интерфейс из пакета java.util.function, который представляет операцию, принимающую один параметр и не возвращающую результат. Consumer используется для выполнения побочных эффектов (side effects) над переданным аргументом, таких как вывод данных, логирование, сохранение в базу данных или другие действия, которые не требуют возврата значения.

Consumer являются обратными вызовами (callbacks), позволяя передавать код как параметр функции.

Определение Consumer

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
    
    // Метод по умолчанию для цепочки consumers
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> {
            accept(t);
            after.accept(t);
        };
    }
}

Основной метод accept(T t) принимает значение типа T и выполняет над ним операцию. Метод по умолчанию andThen() позволяет объединять несколько consumers в цепочку.

Простые примеры использования

Вывод элементов списка:

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerExample {
    
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Иван", "Мария", "Петр");
        
        // Способ 1: с помощью람-выражения
        Consumer<String> printer = name -> System.out.println(name);
        names.forEach(printer);
        
        // Способ 2: напрямую в forEach
        names.forEach(name -> System.out.println("Привет, " + name));
        
        // Способ 3: с использованием ссылки на метод
        names.forEach(System.out::println);
    }
}

Consumer с логированием

import java.util.function.Consumer;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class LoggingConsumer {
    
    // Consumer для логирования с временем
    static Consumer<String> logger = message -> {
        String timestamp = LocalDateTime.now()
            .format(DateTimeFormatter.ISO_LOCAL_TIME);
        System.out.println("[" + timestamp + "] " + message);
    };
    
    public static void main(String[] args) {
        logger.accept("Приложение запущено");
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        logger.accept("Операция завершена");
    }
}

Consumer в Stream API

Consumer часто используется с потоками данных для обработки элементов:

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class StreamConsumer {
    
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        
        // forEach принимает Consumer
        numbers.stream()
            .filter(n -> n % 2 == 0)
            .forEach(n -> System.out.println("Чётное число: " + n));
        
        // Использование peek для отладки (тоже Consumer)
        numbers.stream()
            .filter(n -> n > 2)
            .peek(n -> System.out.println("Обрабатываю: " + n))
            .map(n -> n * 2)
            .forEach(n -> System.out.println("Результат: " + n));
    }
}

Consumer с объектами

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class UserProcessor {
    
    static class User {
        String name;
        int age;
        
        User(String name, int age) {
            this.name = name;
            this.age = age;
        }
        
        @Override
        public String toString() {
            return "User{" + "name='" + name + "', age=" + age + "'}'";
        }
    }
    
    public static void main(String[] args) {
        List<User> users = Arrays.asList(
            new User("Иван", 28),
            new User("Мария", 35),
            new User("Петр", 22)
        );
        
        // Consumer для сохранения в БД (имитация)
        Consumer<User> saveToDb = user -> {
            System.out.println("Сохраняю: " + user.name + " в БД");
            // db.save(user);
        };
        
        // Consumer для отправки уведомления
        Consumer<User> sendNotification = user -> {
            System.out.println("Отправляю уведомление пользователю " + user.name);
            // emailService.send(user.email, "Добро пожаловать!");
        };
        
        users.forEach(saveToDb.andThen(sendNotification));
    }
}

Цепочка Consumer с andThen()

import java.util.function.Consumer;

public class ConsumerChain {
    
    public static void main(String[] args) {
        // Создаём несколько consumers
        Consumer<Integer> printNumber = n -> System.out.println("Число: " + n);
        Consumer<Integer> printSquare = n -> System.out.println("Квадрат: " + (n * n));
        Consumer<Integer> printCube = n -> System.out.println("Куб: " + (n * n * n));
        
        // Объединяем в цепочку с помощью andThen()
        Consumer<Integer> chain = printNumber
            .andThen(printSquare)
            .andThen(printCube);
        
        // Выполняем всю цепочку для каждого числа
        for (int i = 1; i <= 3; i++) {
            System.out.println("--- Число " + i + " ---");
            chain.accept(i);
        }
    }
}

// Результат:
// --- Число 1 ---
// Число: 1
// Квадрат: 1
// Куб: 1
// --- Число 2 ---
// Число: 2
// Квадрат: 4
// Куб: 8

BiConsumer — Consumer с двумя параметрами

import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;

public class BiConsumerExample {
    
    public static void main(String[] args) {
        Map<String, Integer> ages = new HashMap<>();
        ages.put("Иван", 28);
        ages.put("Мария", 35);
        ages.put("Петр", 22);
        
        // BiConsumer для forEach в Map
        BiConsumer<String, Integer> printEntry = (name, age) -> 
            System.out.println(name + " - " + age + " лет");
        
        ages.forEach(printEntry);
    }
}

Практический пример: обработчик событий

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class EventSystem {
    
    static class Event {
        String type;
        String message;
        
        Event(String type, String message) {
            this.type = type;
            this.message = message;
        }
    }
    
    static class EventBus {
        private List<Consumer<Event>> subscribers = new ArrayList<>();
        
        // Подписываем consumer на события
        public void subscribe(Consumer<Event> listener) {
            subscribers.add(listener);
        }
        
        // Отправляем событие всем подписчикам
        public void emit(Event event) {
            subscribers.forEach(listener -> listener.accept(event));
        }
    }
    
    public static void main(String[] args) {
        EventBus bus = new EventBus();
        
        // Логирование
        Consumer<Event> logger = event -> 
            System.out.println("[LOG] " + event.type + ": " + event.message);
        
        // Отправка уведомления
        Consumer<Event> notifier = event -> {
            if ("error".equals(event.type)) {
                System.out.println("[ALERT] Ошибка: " + event.message);
            }
        };
        
        // Сохранение в архив
        Consumer<Event> archiver = event -> 
            System.out.println("[ARCHIVE] Сохранено в архив: " + event.type);
        
        // Подписываемся
        bus.subscribe(logger);
        bus.subscribe(notifier);
        bus.subscribe(archiver);
        
        // Генерируем события
        bus.emit(new Event("info", "Приложение запущено"));
        bus.emit(new Event("error", "Потеря соединения"));
    }
}

Consumer vs Function

ConsumerFunction
Принимает параметр, не возвращает результатПринимает параметр, возвращает результат
void accept(T t)R apply(T t)
Используется для побочных эффектовИспользуется для трансформации
Пример: вывод, логирование, сохранениеПример: фильтр, маппинг, расчёты

Когда использовать Consumer

  • Логирование и отладка — вывод информации
  • Сохранение данных — в БД, кеш, файл
  • Отправка уведомлений — письма, SMS, push
  • Обработка событий — реакция на действия пользователя
  • Валидация и проверки — проверка constraints
  • Трансформация состояния — изменение объектов

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

Что такое интерфейс Consumer? | PrepBro