Как получить следующий элемент из 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
});