Java stream: limit doesnt work with Random().ints().sorted()

Viewed 71

I have following code:

new Random().ints()
            .map(i -> i / 2)
            .limit(100)
            .toArray()

...and it works as expected.

But this doesn't work:

new Random().ints()
            .sorted()
            .map(i -> i / 2)
            .limit(100)
            .toArray()

It throws:

Exception in thread "main" java.lang.IllegalArgumentException: Stream size exceeds max array size

Shouldn't limit shortcircuit the stream and help in restricting it to 100 elements?

1 Answers

The call new Random().ints() returns an infinite stream of pseudo random numbers. When you sort that, it internally uses an array. However, the max size of an array is obviously less than ∞. To fix the issue, use limit and make your stream finite first and then perform the sorting. In fact, this optimizes away the stream processing pipeline since you are sorting only necessary elements. Here's how it looks.

new Random().ints().limit(100).map(i -> i / 2).sorted().toArray();

Update

As per the suggestion made in the below comment, you can further improve it like so.

new Random().ints(100).map(i -> i / 2).sorted().toArray();

The ints procedure produces a stream with exactly 100 pseudo random numbers and with that you can merely dispense with the limit. Moreover, the latter approach is a bit more succinct than the former.

Related