Автор оригинала: Attila Fejér.
1. Введение
API Java Stream знакомит нас с мощной альтернативой для обработки данных.
В этом коротком учебнике мы сосредоточимся на peek () , часто неправильно метод.
2. Быстрый пример
Давайте и пачкаем руки и попробуем использовать peek () . У нас есть поток имен, и мы хотим распечатать их на консоли.
С peek () ожидает Потребитель
StreamnameStream = Stream.of("Alice", "Bob", "Chuck"); nameStream.peek(System.out::println);
Тем не менее, фрагмент выше не производит выхода. Чтобы понять, почему, давайте сделаем быстрое обновление на аспекты жизненного цикла потока.
3. Промежуточные и терминальные операции
Напомним, что потоки имеют три части: источник данных, ноль или более промежуточных операций, а также нулевой или один терминал операции.
Источник обеспечивает элементы конвейера.
Промежуточные операции получают элементы один за другим и обработать их. Все промежуточные операции ленивы, и, как результат, никакие операции не будут иметь никакого эффекта до тех пор, пока трубопровод не начнет работать.
Операции терминала означают конец жизненного цикла потока. Самое главное для нашего сценария, они инициировать работу в трубопроводе .
4. peek () Использование
Причина peek () не работает в нашем первом примере является то, что это промежуточные операции, и мы не применять терминал эксплуатационая к трубопроводу. Кроме того, мы могли бы использовать forEach () с тем же аргументом, чтобы получить желаемое поведение:
StreamnameStream = 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 () может быть полезен в другом сценарии: когда мы хотим изменить внутреннее состояние элемента . Например, предположим, что мы хотим преобразовать имя пользователя в нижний регистр перед печатью:
StreamuserStream = 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 .