Для чего используется метод peek() в Java Stream API?

Ответ

Метод peek() — это промежуточная (intermediate) операция в Stream API, которая позволяет выполнить побочное действие (например, логирование или отладку) для каждого элемента потока, не изменяя сам поток.

Основное назначение — отладка:

List<String> result = names.stream()
    .peek(name -> System.out.println("Before filter: " + name))
    .filter(name -> name.length() > 3)
    .peek(name -> System.out.println("After filter: " + name))
    .collect(Collectors.toList());

Ключевые особенности peek():

  1. Stateless (не хранит состояние): Не изменяет данные в потоке.
  2. Lazy (ленивый): Действие выполнится только при вызове терминальной операции.
  3. Не для модификации: Не предназначен для изменения состояния элементов или внешних переменных (для этого используйте map или forEach).

Практическое правило: peek() следует использовать преимущественно для отладки. В production-коде для побочных эффектов часто предпочтительнее явный цикл или операция forEach.

Ответ 18+ 🔞

А, ну ты смотри, опять про этот peek() заговорили! Ну, блядь, классика жанра, как Герасим с Муму, только в мире стримов. Сейчас я тебе так объясню, что ты, сука, офигеешь.

Вот представь себе, ты на конвейере стоишь, а по нему элементы плывут, как бревна по реке. И есть у тебя такой мудак-надзиратель, который ничего не делает, только в свой блокнотик записывает: «Ага, вот это бревно проплыло, а вот это — уже отпиленное». Это и есть peek(). Он, блядь, промежуточный, то есть сам по себе нихуя не решает — он просто подсматривает, сука, и всё.

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

List<String> result = names.stream()
    .peek(name -> System.out.println("До фильтра, блядь: " + name)) // Смотрит, что входит
    .filter(name -> name.length() > 3) // А вот тут уже реальная работа
    .peek(name -> System.out.println("После фильтра, ёпта: " + name)) // Смотрит, что вышло
    .collect(Collectors.toList());

Видишь? Он как тот немой Герасим — стоит, смотрит на поток, мычит «Му-му» в консоль, но сами элементы не трогает. Силы у него, блядь, необоснованно много для такой простой работы, но он её делает.

Теперь три главных пункта, чтобы не обосраться:

  1. Stateless (бессердечный, блядь). Он нихуя не запоминает. Пришел элемент — он на него посмотрел, пописал в лог и забыл. Как будто и не было.
  2. Lazy (ленивая жопа). Пока ты не скажешь «собирай!» (collect) или «делай что-нибудь!» (терминальная операция), он пальцем о палец не ударит. Будет спать, сука, и снится ему ничего.
  3. Не для пиздежа с данными! Это, блядь, самое важное. Он не для того, чтобы ты там элементы менял или в глобальную переменную что-то писал. Для этого есть map — работяга, или forEach — тот, кто в конце конвейера всё по местам расставляет. Peek() — просто зритель, мартышлюшка с блокнотом.

Практическое правило, которое даже дурак запомнит: peek() — это для отладки, когда у тебя волнение ебать и терпения ноль. В нормальном, продакшен-коде, если тебе нужно что-то сделать с элементами — не выёбывайся, используй map или в конце forEach. А то получится, как в той истории: «Зачем топить-то, блядь?» — а потом совесть загложет, что неправильный инструмент применил. Пиздец, короче.