Рубрики
Без рубрики

Java 8 Потоки заглянуть () API

Узнайте о методе peek () и исследуйте жизненный цикл потока.

Автор оригинала: Attila Fejér.

1. Введение

API Java Stream знакомит нас с мощной альтернативой для обработки данных.

В этом коротком учебнике мы сосредоточимся на peek () , часто неправильно метод.

2. Быстрый пример

Давайте и пачкаем руки и попробуем использовать peek () . У нас есть поток имен, и мы хотим распечатать их на консоли.

С peek () ожидает Потребитель в качестве единственного аргумента, кажется, хорошо подходят, так что давайте попробуем:

Stream nameStream = Stream.of("Alice", "Bob", "Chuck");
nameStream.peek(System.out::println);

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

3. Промежуточные и терминальные операции

Напомним, что потоки имеют три части: источник данных, ноль или более промежуточных операций, а также нулевой или один терминал операции.

Источник обеспечивает элементы конвейера.

Промежуточные операции получают элементы один за другим и обработать их. Все промежуточные операции ленивы, и, как результат, никакие операции не будут иметь никакого эффекта до тех пор, пока трубопровод не начнет работать.

Операции терминала означают конец жизненного цикла потока. Самое главное для нашего сценария, они инициировать работу в трубопроводе .

4. peek () Использование

Причина peek () не работает в нашем первом примере является то, что это промежуточные операции, и мы не применять терминал эксплуатационая к трубопроводу. Кроме того, мы могли бы использовать forEach () с тем же аргументом, чтобы получить желаемое поведение:

Stream nameStream = Stream.of("Alice", "Bob", "Chuck");
nameStream.forEach(System.out::println);

peek () ‘ы Javadoc страница говорит: ” Этот метод существует в основном для поддержки отладки, где вы хотите увидеть элементы, как они протекают мимо определенной точки в “.

Рассмотрим этот фрагмент с той же страницы Javadoc:

Stream.of("one", "two", "three", "four")
  .filter(e -> e.length() > 3)
  .peek(e -> System.out.println("Filtered value: " + e))
  .map(String::toUpperCase)
  .peek(e -> System.out.println("Mapped value: " + e))
  .collect(Collectors.toList());

Это показывает, как мы наблюдаем элементы, которые прошли каждую операцию.

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

Stream userStream = Stream.of(new User("Alice"), new User("Bob"), new User("Chuck"));
userStream.peek(u -> u.setName(u.getName().toLowerCase()))
  .forEach(System.out::println);

Кроме того, мы могли бы использовать карта () , но peek () удобнее, так как мы не хотим заменять элемент.

5. Заключение

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

И, как обычно, примеры доступны более на GitHub .