Скажем, у нас есть этот поток
Stream.of("a", "b", "err1", "c", "d", "err2", "e", "f", "g", "h", "err3", "i", "j");
и я хочу сохранить на карте пары соседних строк, в которых первая начинается с "err".
То, что я думал, это что-то вроде этого
Map<String, String> map = new HashMap<>();
Stream.of("a", "b", "err1", "c", "d", "err2", "e", "f", "g", "h", "err3", "i", "j")
.reduce((acc, next) -> {
if (acc.startsWith("err"))
map.put(acc,next);
if (next.startsWith("err"))
return next;
else
return "";
});
Но я не полностью удовлетворен этим по двум основным причинам.
- Я использую функцию "неправильное использование"
reduce
. В Stream API каждая функция имеет четкую и четко определенную цель:max
предполагается исчислять максимальное значение,filter
должен фильтровать на основе условия,reduce
должен генерировать добавочно накопленное значение и так далее. - Это не позволяет мне использовать мощные механизмы Streams: что, если бы я хотел ограничить мой поиск первыми двумя результатами?
Здесь я использовал reduce
, потому что (насколько мне известно) это единственная функция, которая позволяет вам сравнить пару значений, которые вы можете каким-то образом привести к чему-то, аналогичному понятиям "текущее значение" и "следующее значение".
Есть ли более простой способ? Что-то, что позволяет вам перебирать поток с учетом более чем одного значения для каждой итерации?
ИЗМЕНИТЬ
То, о чем я думаю, это какой-то механизм, который, учитывая текущий элемент, позволяет вам определить "окно элементов" для каждой итерации.
Что-то вроде
<R> Stream<R> mapMoreThanOne(
int elementsBeforeCurrent,
int elementsAfterCurrent,
Function<List<? super T>, ? extends R> mapper);
вместо
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
Это будет мощное "обновление" для текущего API.
EDIT2
Я ценю усилия людей, предлагающих их решение, но проблема заключается не в самом алгоритме. Существуют разные способы достижения моей цели, объединяя потоки, индексы, временные переменные для хранения предыдущих значений... но мне было интересно, существует ли какой-либо метод в Stream API, который был разработан для задачи обработки элементов, отличных от текущего не нарушая "русскую парадигму". Что-то вроде этого
List<String> list =
Stream.of("a", "b", "err1", "c", "d", "err2", "e", "f", "g", "h", "err3", "i", "j")
.filterFunctionImWonderingIfExist(/*filters couples of elements*/)
.limit(2)
.collect(Collectors.toList());
Учитывая ответы, я думаю, что нет "ясного и быстрого" решения, если не использовать библиотеку StreamEx