0

I want to execute two streams simultaneously and generate a third stream as a combination of the first two.Suppose I have the following two streams

Stream<String> a = Stream.of("f","b","z");
Stream<String> b = Stream.of("foo","bar","baz");

and I want to generate a new one from these two which would be equivalent to this one

Stream<String> c = Stream.of("f:foo","b:bar","z:baz");

What I have found so far is Stream.concat or Stream.of

 Stream<String> result = Stream.concat(a, b); or
 Stream<String> result = Stream.of(a, b).flatMap(s -> s);

where both are rather attached to each other and correspond to this here

Stream.of("f","b","z","foo","bar","baz");

So far my workaround is to collect the elements of the two streams to one list each and iterate over both lists to concatenate the single elements and turn the result list into a stream. Is there a shorter way or an existing function in strem api to work simultaneously over two streams?

List<String> aList = a.collect(Collectors.toList());
List<String> bList = b.collect(Collectors.toList());
List<String> result = new ArrayList<>();
for(int i = 0; i< aList.size(); i++){
    result.add(aList.get(i)+":"+bList.get(i));
}
Stream<String> cc = result.stream();
Trillian
  • 411
  • 4
  • 15

2 Answers2

6

This operation is usually called zip, and it doesn't exist as a function in the Stream API. It's kinda hard to implement it yourself, as you can see from this answer: https://stackoverflow.com/a/23529010/4137489

The function is implemented in the Google Guava library though:

https://guava.dev/releases/23.0/api/docs/com/google/common/collect/Streams.html#zip-java.util.stream.Stream-java.util.stream.Stream-java.util.function.BiFunction-

You can use it like this:

Streams.zip(a, b, (aElem, bElem) -> aElem + ":" + bElem));
marstran
  • 26,413
  • 5
  • 61
  • 67
  • 1
    Baeldung has an article about the topic, suggesting two third-part implementations (Guava and jOOL): https://www.baeldung.com/java-collections-zip – Luis Iñesta Jul 29 '19 at 14:20
  • Thank you very much for the quick reply and the links. I didn't know the keyword "zip" and so I didn't find anything useful with my search terms. The function in the guava library is exactly what I need. – Trillian Jul 29 '19 at 14:22
1

You could use the IntStream.range() method:

IntStream.range(0, aList.size()).mapToObj(index -> aList.get(index) + ":" + bList.get(index)).collect(Collectors.toList());
androberz
  • 744
  • 10
  • 25