3

Example;

IntStream a = create(3, 1);  // => [0,0,1]
IntStream b = create(5, 2);  // => [0,0,0,0,2]

The first stream gives an infinite stream of [0,0,1,0,0,1...] and the second an infinite stream of [0,0,0,0,2,0,0,0,0,2,...].

The result stream is ri = ai + bi meaning that I just want to take the sum of the elements at the same position from each stream.

Is this possible in Java ?

YCF_L
  • 51,266
  • 13
  • 85
  • 129
rogergl
  • 3,193
  • 2
  • 25
  • 47
  • 1
    Implementing a `Spliterator` is apparently the best method: https://stackoverflow.com/q/30685623/1896169 – Justin May 22 '17 at 19:37
  • what is `create` ? – YCF_L May 22 '17 at 19:40
  • @YCF_L. This is clearly explained in the question. – Mad Physicist May 22 '17 at 19:42
  • 2
    Also very relevant: https://stackoverflow.com/q/17640754/2988730 – Mad Physicist May 22 '17 at 19:43
  • i'm really don't get it, i'm not familiar so much with streams so i don't know how create look like @MadPhysicist can you guide me please? – YCF_L May 22 '17 at 19:43
  • @YCF_L For test purposes, just have an ArrayList with 15 elements for each case and call `toStream` or whatever on it. No need to make this complicated – Mad Physicist May 22 '17 at 19:45
  • So, the result for the given example with `[0, 0, 1, …]` and `[0, 0, 0, 0, 2, …]` would be `[0, 0, 1, 0, 2, 1, …]`? – beatngu13 May 22 '17 at 19:56
  • @beatngu13. If the 15th element is 3, then yes. This looks like FizzBuzz now that you put it that way. – Mad Physicist May 22 '17 at 19:58
  • 2
    Possible duplicate of [Zipping streams using JDK8 with lambda (java.util.stream.Streams.zip)](https://stackoverflow.com/questions/17640754/zipping-streams-using-jdk8-with-lambda-java-util-stream-streams-zip) – Ole V.V. May 22 '17 at 20:08

2 Answers2

2

You can use Guava's Streams.zip() helper:

IntStream sum(IntStream a, IntStream b) {
    return Streams.zip(a.boxed(), b.boxed(), Integer::sum)
            .map(Integer::intValue);
}
shmosel
  • 45,768
  • 6
  • 62
  • 130
1

You can define your own Spliterator to create a stream from it later.

import java.util.Comparator;
import java.util.Spliterators;
import java.util.function.IntConsumer;

public class SumSpliterator extends Spliterators.AbstractIntSpliterator {
    private OfInt aSplit;
    private OfInt bSplit;

    SumSpliterator(OfInt a, OfInt b) {
        super(Math.min(a.estimateSize(), b.estimateSize()), Spliterator.ORDERED);
        aSplit = a;
        bSplit = b;
    }

    @Override
    public boolean tryAdvance(IntConsumer action) {
        SummingConsumer consumer = new SummingConsumer();
        if (aSplit.tryAdvance(consumer) && bSplit.tryAdvance(consumer)) {
            action.accept(consumer.result);
            return true;
        }
        return false;
    }

    static class SummingConsumer implements IntConsumer {
        int result;
        @Override
        public void accept(int value) {
            result += value;
        }
    }
}

Then create a stream and check the results

IntStream a = //create stream a
IntStream b = //create stream b
SumSpliterator spliterator = new SumSpliterator(a.spliterator(), b.spliterator());
Stream<Integer> stream = StreamSupport.stream(spliterator, false);
stream.limit(20).forEach(System.out::println);
Dmitry P.
  • 815
  • 5
  • 14