Collect successive pairs from a stream

Aleksandr Dubinsky picture Aleksandr Dubinsky · Dec 9, 2013 · Viewed 58.4k times · Source

Given a stream such as { 0, 1, 2, 3, 4 },

how can I most elegantly transform it into given form:

{ new Pair(0, 1), new Pair(1, 2), new Pair(2, 3), new Pair(3, 4) }

(assuming, of course, I've defined class Pair)?

Edit: This isn't strictly about ints or primitive streams. The answer should be general for a stream of any type.

Answer

Stuart Marks picture Stuart Marks · Dec 11, 2013

The Java 8 streams library is primarily geared toward splitting streams into smaller chunks for parallel processing, so stateful pipeline stages are quite limited, and doing things like getting the index of the current stream element and accessing adjacent stream elements are not supported.

A typical way to solve these problems, with some limitations, of course, is to drive the stream by indexes and rely on having the values being processed in some random-access data structure like an ArrayList from which the elements can be retrieved. If the values were in arrayList, one could generate the pairs as requested by doing something like this:

    IntStream.range(1, arrayList.size())
             .mapToObj(i -> new Pair(arrayList.get(i-1), arrayList.get(i)))
             .forEach(System.out::println);

Of course the limitation is that the input cannot be an infinite stream. This pipeline can be run in parallel, though.