Как получить следующий элемент из List используя потоки Java 8?
Если я перебираю List, я хочу сравнить текущий со следующим элементом списка.
Это выполнимо с использованием Java 8 Stream?
Как получить следующий элемент из List используя потоки Java 8?
Если я перебираю List, я хочу сравнить текущий со следующим элементом списка.
Это выполнимо с использованием Java 8 Stream?
Моя бесплатная библиотека StreamEx позволяет обрабатывать пары элементов потока с помощью дополнительных pairMap промежуточная операция. Вот так:
StreamEx.of(input).pairMap((current, next) -> doSomethingWith(current, next));
Где input - это Collection, массив или Stream. Например, таким образом вы можете легко проверить, отсортирован ли вход:
boolean isSorted = StreamEx.of(input)
.pairMap((current, next) -> next.compareTo(current))
.allMatch(cmp -> cmp >= 0);
Также существует операция forPairs, которая является аналогом forEach для всех пар входных элементов:
StreamEx.of(input).forPairs((current, next) -> doSomethingWith(current, next));
Эти функции прекрасно работают с любым источником потока (либо произвольным доступом, либо нет), и полностью поддерживают параллельные потоки.
Один из способов - создать индекс IntStream для индексов и получить элементы List по их индексу. Это эффективно, только если List поддерживает произвольный доступ (т.е. Если ваш List является LinkedList, это будет плохая идея, так как list.get(i) не принимает постоянного времени).
Например:
IntStream.range(0,list.size()-1).forEach(i -> {
doSomething(list.get(i),list.get(i+1));
});
Другой способ - сохранить последний элемент в массиве:
List<Element> list = ...
Element[] arr = new Element[1];
list.stream().forEach(e -> {
if (arr[0] != null)
doSomething(arr[0],e);
arr[0]=e;
});
Это будет работать только для последовательных потоков.
Вы всегда выполняете одно из следующих действий:
Реализации обоих решений можно увидеть в этой теме: Можно ли получить следующий элемент в потоке?
Мне пришлось сделать то же самое и сравнить различия элементов потока (первоначально массив). Поэтому я использовал метод в качестве параметра для UnaryOperator, который .map() ожидает следующим образом... и он работал для меня без каких-либо специальных штуковин:
import java.util.Arrays;
class streamDiffUtil {
public static void main(String[] args) {
int[] elements = {1,2,5};
int result = Arrays.stream(elements)
.map(value -> calcMaxDiff(value, elements))
.max()
.getAsInt();
System.out.println(result);
}
private static int calcMaxDiff(int j, int[] elements) {
return Arrays.stream(elements)
.map(value -> Math.abs(j-value))
.max().getAsInt();
}
}
Было бы неплохо узнать, как метод calcMaxDiff приравнивается к UnaryIntOperator в сигнатуре .map. Это немного за мной. Надеюсь, это поможет вам.
Stream.reduce может быть использован, в зависимости от цели. Как вы сказали, вы хотите сравнить последовательные элементы, следующее выдает "Same 3":
Stream.of(1,2,3,3).reduce((a,b)->{
if(a==b) System.out.println("Same "+a);
return b; // will be "a" for next reduction
});