There is no function similar to zipWith
in the Streams API of Java. It came to be implemented in a build of Java 8 but was removed because, in the view of those responsible for the language, such functionality would be better provided by libraries, or even each developer could implement its own version that would needs.
Among the issues he cited are:
- is a language of other languages that does not adapt well to Java because of the inexistence of tuples and other types;
- In the current version of Java, it is not possible to create a version that accepts primitive types, which can cause performance problems due to boxing and unboxing variables, in addition of the need to create new SAM types ;
- difficult to parallelize;
- Multiple ways to handle Streams of different sizes. Which should be chosen?
You can follow the whole discussion about it here .
So you have to implement your own solution, or use some library that has such functionality, such as guava . p>
As a guide, guava implements this method this way :
/**
* Returns a stream in which each element is the result of passing the corresponding elementY of
* each of {@code streamA} and {@code streamB} to {@code function}.
*
* <p>For example:
*
* <pre>{@code
* Streams.zip(
* Stream.of("foo1", "foo2", "foo3"),
* Stream.of("bar1", "bar2"),
* (arg1, arg2) -> arg1 + ":" + arg2)
* }</pre>
*
* <p>will return {@code Stream.of("foo1:bar1", "foo2:bar2")}.
*
* <p>The resulting stream will only be as long as the shorter of the two input streams; if one
* stream is longer, its extra elements will be ignored.
*
* <p>Note that if you are calling {@link Stream#forEach} on the resulting stream, you might want
* to consider using {@link #forEachPair} instead of this method.
*
* <p><b>Performance note:</b> The resulting stream is not <a
* href="http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html">efficiently splittable</a>.
* This may harm parallel performance.
*/
public static <A, B, R> Stream<R> zip(
Stream<A> streamA, Stream<B> streamB, BiFunction<? super A, ? super B, R> function) {
checkNotNull(streamA);
checkNotNull(streamB);
checkNotNull(function);
boolean isParallel = streamA.isParallel() || streamB.isParallel(); // same as Stream.concat
Spliterator<A> splitrA = streamA.spliterator();
Spliterator<B> splitrB = streamB.spliterator();
int characteristics =
splitrA.characteristics()
& splitrB.characteristics()
& (Spliterator.SIZED | Spliterator.ORDERED);
Iterator<A> itrA = Spliterators.iterator(splitrA);
Iterator<B> itrB = Spliterators.iterator(splitrB);
return StreamSupport.stream(
new AbstractSpliterator<R>(
Math.min(splitrA.estimateSize(), splitrB.estimateSize()), characteristics) {
@Override
public boolean tryAdvance(Consumer<? super R> action) {
if (itrA.hasNext() && itrB.hasNext()) {
action.accept(function.apply(itrA.next(), itrB.next()));
return true;
}
return false;
}
},
isParallel)
.onClose(streamA::close)
.onClose(streamB::close);
}
Note: The checkNotNull
method is also part of guava. If you want to use such an implementation without using the library, you can replace it with the Objects.requireNonNull
method.