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

Улучшения API потока Java 9

Краткое и практическое руководство по дополнениям Java 9 Stream API

Автор оригинала: baeldung.

1. Обзор

В этом кратком обзоре мы сосредоточимся на новых интересных улучшениях API Stream, которые появятся в Java 9.

2. Поток Принимает Время/Сбрасывает Время

Обсуждения этих методов неоднократно появлялись в StackOverflow (наиболее популярным является этот ).

Представьте, что мы хотим создать Поток из Строки s, добавив один символ к предыдущему значению Потока до тех пор, пока длина текущего значения в этом потоке не станет меньше, чем 10 .

Как бы мы решили эту проблему в Java 8? Мы могли бы использовать одну из промежуточных операций короткого замыкания, таких как limit , allMatch , которые на самом деле служат для других целей, или написать нашу собственную реализацию на основе разделителя , что, в свою очередь, усложняет такую простую проблему.

С Java 9 решение простое:

Stream stream = Stream.iterate("", s -> s + "s")
  .takeWhile(s -> s.length() < 10);

Операция takeWhile принимает Предикат , который применяется к элементам для определения самого длинного префикса этих элементов (если поток упорядочен) или подмножества элементов потока (когда поток неупорядочен).

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

  • самый длинный префикс – это непрерывная последовательность элементов потока, соответствующих данному предикату. Первый элемент последовательности является первым элементом этого потока, а элемент, следующий непосредственно за последним элементом последовательности, не соответствует данному предикату
  • подмножество потока представляет собой набор некоторых (но не всех) элементов Потока , соответствующих данному предикату.

После введения этих ключевых терминов мы можем легко понять еще одну новую операцию drop While .

Это делает прямо противоположное take While . Если поток упорядочен, drop While возвращает поток, состоящий из оставшихся элементов этого потока после удаления самого длинного префикса элементов, соответствующих данному предикату.

В противном случае, если Поток неупорядочен, drop While возвращает поток, состоящий из оставшихся элементов этого потока после удаления подмножества элементов, соответствующих данному предикату.

Давайте отбросим первые пять элементов, используя предыдущий полученный Поток :

stream.dropWhile(s -> !s.contains("sssss"));

Проще говоря, операция drop While удалит элементы, в то время как данный предикат для элемента возвращает true и прекращает удаление при первом предикате false .

3. Потоковая итерация

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

Новый iterate слегка изменяет этот метод, добавляя предикат, который применяется к элементам, чтобы определить, когда поток должен завершиться. Его использование очень удобно и лаконично:

Stream.iterate(0, i -> i < 10, i -> i + 1)
  .forEach(System.out::println);

Он может быть связан с соответствующим для оператором:

for (int i = 0; i < 10; ++i) {
    System.out.println(i);
}

4. Поток Nullable

Есть некоторые ситуации, когда нам нужно поместить элемент в Поток . Иногда этот элемент может быть null , но мы не хотим , чтобы наш Поток содержал такие значения. Это приводит к написанию либо оператора if , либо тернарного оператора, который проверяет, является ли элемент нулевым.

Предполагая, что переменные коллекция и карта были успешно созданы и заполнены, посмотрите на следующий пример:

collection.stream()
  .flatMap(s -> {
      Integer temp = map.get(s);
      return temp != null ? Stream.of(temp) : Stream.empty();
  })
  .collect(Collectors.toList());

Чтобы избежать такого шаблонного кода, метод ofNullable был добавлен в класс Stream . С помощью этого метода предыдущий образец может быть просто преобразован в:

collection.stream()
  .flatMap(s -> Stream.ofNullable(map.get(s)))
  .collect(Collectors.toList());

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

Мы рассмотрели основные изменения Stream API в Java 9 и то, как эти улучшения помогут нам писать более выразительные программы с меньшими усилиями.

Как всегда, фрагменты кода можно найти на Github .