8

I have an Eclipse Collections IntList. How can I

  1. Create a Java IntStream from this list
  2. Create a Java Stream<Integer> from this list

without copying the elements?

Holger
  • 285,553
  • 42
  • 434
  • 765
Jochen
  • 7,270
  • 5
  • 24
  • 32
  • 5
    `IntStream.range(0, intList.size()).map(intList::get)`. To get a `Stream`, just append `.boxed()`. – Holger Apr 04 '19 at 08:05
  • 2
    @Holger You should post that as an answer. I was thinking the iterator would be the most efficient, but that's also doing constant time array accesses with an incrementing index, so it's about the same. – Sean Van Gorder Apr 04 '19 at 17:14
  • 1
    @SeanVanGorder feel free to include it into your answer, I don’t want to create a new one for a single line of code. By the way, the `IntStream.range` approach is even more efficient in parallel processing, as ranges can be split nicely (unlike an iterator). – Holger Apr 05 '19 at 07:28
  • 2
    When Eclipse Collections 10.0 is released, you will be able to call primitiveStream() on IntList, LongList or DoubleList. – Donald Raab Apr 23 '19 at 06:28

2 Answers2

5

With Eclipse Collections 10.0 you can now call primitiveStream directly on IntList.

IntStream intStream = IntLists.mutable.with(1, 2, 3, 4, 5).primitiveStream();

Stream<Integer> stream = intStream.boxed();
Donald Raab
  • 6,458
  • 2
  • 36
  • 44
4

Edit: Holger's comment found a much clearer solution:

public static IntStream intListToIntStream(IntList intList) {
    return IntStream.range(0, intList.size()).map(intList::get);
}

After looking into the IntIterator code, it turns out the implementation is equivalent to this, so the below solutions are unnecessary. You can even make this more efficient using .parallel().


If you're on Java 9, you can use this method:

public static IntStream intListToIntStream(IntList intList) {
    IntIterator intIter = intList.intIterator();
    return IntStream.generate(() -> 0)
            .takeWhile(i -> intIter.hasNext())
            .map(i -> intIter.next());
}

Otherwise, I don't see a better solution than wrapping the IntIterator as a PrimitiveIterator.OfInt and building a stream out of that:

public static IntStream intListToIntStream(IntList intList) {
    IntIterator intIter = intList.intIterator();
    return StreamSupport.intStream(Spliterators.spliterator(new PrimitiveIterator.OfInt() {
        @Override
        public boolean hasNext() {
            return intIter.hasNext();
        }
        @Override
        public int nextInt() {
            return intIter.next();
        }
    }, intList.size(), Spliterator.ORDERED), false);
}

Either way, you can just get a Stream<Integer> by calling IntStream.boxed().

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
Sean Van Gorder
  • 3,393
  • 26
  • 26