简体   繁体   中英

Creating a stream by combining the result of multiple streams

How can I convert multiple Streams into one Stream? For example, I have 3 IntStreams and I want to combine them into one Stream of int arrays.

In the Javadoc, most Stream operations take one stream as input, and the concat doesn't answer my use case.

Here's what I had in mind

Stream 1: 1, 2, 3
Stream 2: 4, 5, 6
Combined Stream ex1: [1,4],[2,5],[3,6]
Combined Stream ex2: 1+4,2+5,3+6
Combined Stream ex3: new MyObject(1,4), new MyObject(2,5), new MyObject(3,6)

Sadly, there is nothing native to the Stream that does this for you. An unfortunate shortcoming to the API.

That said, you could do this by taking out an Iterator on each of the streams, similar to:

public static <T,U,R> Stream<R> zipStreams (Stream<T> a, Stream<U> b, BiFunction<T,U,R> zipFunc) {
    Iterator<T> itA = a.iterator();
    Iterator<U> itB = b.iterator();
    Iterator<R> itRet = new Iterator<R>() {

        @Override
        public boolean hasNext() {
            return itA.hasNext() && itB.hasNext();
        }

        @Override
        public R next() {
            return zipFunc.apply(itA.next(), itB.next());
        }

    };
    Iterable<R> ret = () -> itRet;
    return StreamSupport.stream(ret.spliterator(), a.isParallel() || b.isParallel());
}

In functional terms, the problem comes down to zipping a list of streams, and applying a custom zipper for each elements.

There is no facility to do that directly with the Stream API. We can use 3rd party libraries, like the protonpack library, that provides a zip method to do that. Considering the data:

List<Stream<Integer>> streams = Arrays.asList(Stream.of(1,2,3), Stream.of(4,5,6));

you can have

Stream<Integer> stream = StreamUtils.zip(streams, l -> l.stream().mapToInt(i -> i).sum());
// the Stream is now "1+4,2+5,3+6"

or

Stream<Integer[]> stream = StreamUtils.zip(streams, l -> l.toArray(new Integer[l.size()]));
// the Stream is now "[1,4][2,5][3,6]"

The mapper takes the list of elements to zip and returns the zipped value. In the first example, it sums the value together, while it returns an array in the second.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM