javajava-8java-streamsequencealternating

merge streams to produce alternating sequence using lambda or Stream API


I have some code which returns a Stream as intended, but maybe it can be replaced with some type of lambda or stream() operation instead of exhausting the iterators in a while loop?

It is just a method that alternates elements from the streams first and second and stops when one of them runs out of elements.

public static <T>Stream<T> alternatingSequence(Stream<T> first, Stream<T> second){
        Iterator<T> iteratorFirst = first.iterator();
        Iterator<T> iteratorSecond = second.iterator();
        Stream<T> resultStream = Stream.empty();
        while (iteratorFirst.hasNext() && iteratorSecond.hasNext()){
            resultStream = Stream.concat(resultStream, Stream.of(iteratorFirst.next(), iteratorSecond.next()));
        }
        return resultStream;
    }
}

Solution

  • Using Guava's Streams.zip you can combine the two streams into a stream of two-element streams, which you may then simply flatten to produce an alternating sequence:

    return Streams.zip(first, second, (arg1, arg2) -> Stream.of(arg1, arg2))
        .flatMap(Function.identity());
    

    One caveat is that the resulting stream is not efficiently splittable (see linked doc). This may harm parallel performance.

    Note:

    If you don't have access to Guava then you can implement your own zip(a, b, bifunc) as shown here.