Как получить последний элемент потока в Java?

Как получить последний элемент потока в Java?

1. обзор

API JavaStream был основной функцией выпуска Java 8. Streams представляют собой ленивые последовательности объектов и предоставляют богатый, плавный и монадический API.

В этой статье мы кратко рассмотрим способы получения последнего элементаStream.. Имейте в виду, чтоdue to the nature of streams, it’s not a natural operation. Всегда следите за тем, чтобы вы не работали с бесконечнымиStreams.

2. Использование APIReduce

Проще говоря,Reduce сокращает набор элементов вStream до одного элемента.

В этом случае мы сократим набор элементов, чтобы получить последний элемент изStream.. Имейте в виду, чтоthis method will only return deterministic results for sequential Streams.

Давайте возьмемList из значенийString, получимStream изList, а затем уменьшим:

List valueList = new ArrayList<>();
valueList.add("Joe");
valueList.add("John");
valueList.add("Sean");

Stream stream = valueList.stream();
stream.reduce((first, second) -> second)
  .orElse(null);

Здесь поток сокращается до уровня, на котором он остается только с последним элементом. Если поток пуст, он вернет значениеnull.

2. Использование функции пропуска

Другой способ получить последний элемент потока -by skipping all the elements before it. Этого можно добиться с помощью функцииSkip классаStream. Имейте в виду, что в этом случае мы потребляемStream дважды, поэтому есть явное влияние на производительность.

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

Вот пример кода, получающего последний элемент с использованиемskip:

List valueList = new ArrayList();
valueList.add("Joe");
valueList.add("John");
valueList.add("Sean");

long count = valueList.stream().count();
Stream stream = valueList.stream();

stream.skip(count - 1).findFirst().get();

“Sean” оказывается последним элементом.

4. Получение последнего элемента бесконечного потока

Попытка получить последний элемент бесконечного потока привела бы к бесконечной последовательности вычислений, выполненных на бесконечных элементах. Иskip, иreduce не вернутся из выполнения оценки, если мы не ограничим бесконечный поток определенным количеством элементов с помощью операцииlimit.

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

Stream stream = Stream.iterate(0, i -> i + 1);
stream.reduce((first, second) -> second).orElse(null);

Следовательно, поток не вернется из оценки и закончитсяhalting the execution of the program.

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

Мы видели разные способы получения последнего элементаStream с использованием APIreduce иSkip. Мы также выяснили, почему это невозможно с бесконечными потоками.

Мы увидели, что получить последний элемент изStream непросто по сравнению с получением его из других структур данных. Это связано с ленивым характеромStreams, которые не вычисляются, если не вызывается функция терминала иwe never know if the currently evaluated element is the last one.

Фрагменты кода можно найтиover on GitHub.