Существует множество подходов для получения требуемого результата с использованием потоков.
Но, прежде всего, вы не обязаны использовать Stream API
, а в случае работы со спискамииз десятков и сотен элементов я бы предложил использовать простые старые итерации списка.
Просто попробуйте, например, пример кода ниже.
Мы легко можем увидеть две поверхностные проблемы, возникающие из-за природы потокови их несовместимость с самой идеей сопряжения ее элементов:
- необходимо применить функцию с сохранением состояния, которая действительно сложна для использования в
map()
и должна рассматриваться как грязное кодирование;и отображение приводит к появлению некоторых нулей в четных местах, которые должны быть отфильтрованы должным образом; - возникают проблемы, когда поток содержит нечетное количество элементов, и вы никогда не сможете предсказать, если это так.
Если вы решите использовать потоки, то для ясности нам понадобится индивидуальная реализация Iterator, Spliterator или Collector - в зависимости от требований.В любом случае, есть пара неочевидных угловых случаев, которые вы не захотите реализовать самостоятельно, поэтому можете попробовать множество сторонних потоковых библиотек.Двумя наиболее популярными являются Streamex и RxJava .Определенно, у них есть инструменты для сопряжения потоковых элементов ... но не забудьте проверить производительность в вашем случае!
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Stream;
public class Sample
{
public static void main(String... arg)
{
String path = "somewhere";
Stream<Converter> stream = Stream.of(0, 15, 25, 30).map(
new Function<Integer, Converter>()
{
int previous;
boolean even = true;
@Override
public Converter apply(Integer current)
{
Converter converter = even ? null : new Converter(path, previous, current);
even = !even;
previous = current;
return converter;
}
}).filter(Objects::nonNull);
stream.forEach(System.out::println);
}
static class Converter
{
private final String path;
private final int start;
private final int end;
Converter(String path, int start, int end)
{
this.path = path;
this.start = start;
this.end = end;
}
public String toString()
{
return String.format("Converter[%s,%s,%s]", path, start, end);
}
}
}