2

IntStream.range(x,y) would return a stream from x(inclusive) and y(exclusive). IntStream.rangeClosed(x,y) would return a stream from x(inclusive) and y(inclusive).

I expected rangeClosed(x,y) to invoke range(x,y-1) or range(x,y) to invoke rangeClosed(x,y-1). But while looking at the source code for range it was like:

if (startInclusive >= endExclusive) {
    return empty();
} else {
    return StreamSupport.intStream(
    new Streams.RangeIntSpliterator(startInclusive, endExclusive, false /*not closed*/), false);
}

The rangeClosed also had a very similar implementation rather than range(x,y+1). The only difference was that the third argument to Streams.RangeIntSpliterator was true instead of false denoting that the range is closed.

This boolean is then used to initialize int last field in Streams.RangeIntSpliterator class and the below comment is mentioned against it:

1 if the range is closed and the last element has not been traversed Otherwise, 0 if the range is open, or is a closed range and all elements have been traversed

Why is such an implementation necessary instead of range simply calling rangeClosed or the other way round? Is there any significant difference between calling rangeClosed(x,y) instead of range(x,y+1) ?

Gautham M
  • 4,816
  • 3
  • 15
  • 37

1 Answers1

11

Even though there aren't any differences in the normal scenario, it would cause an issue when the input to the methods are min/max limits of Integer.

Assuming that rangeClosed(x,y) invokes range(x,y+1). If you are invoking rangeClosed(0, Integer.MAX_VALUE), then instead of the expected number of iterations (2147483648), the actual number of iterations would be 0, as Integer.MAX_VALUE + 1 would result in an overflow and an empty stream would be returned.

Similar overflow would cause the result to be different in case if an input is Integer.MIN_VALUE.

Gautham M
  • 4,816
  • 3
  • 15
  • 37
  • Open and close intervals are represented using `(open, close]`. Note that `Math.addExact(y, 1)` would fail fast and should be used ideally. – Aniket Sahrawat May 07 '21 at 19:15
  • @AniketSahrawat Sorry, but I am not able to get the point you were trying to convey. Is it like `range(x , Math.addExact(y, 1))` would result in an exception rather than an incorrect result when compared to the `range(x, y+1)` incase when `y` is `MAX_VALUE` ? – Gautham M May 08 '21 at 08:47
  • Yes indeed. Try `range(0 , Math.addExact(Integer.MAX_VALUE, 1))`, it will result in an exception. – Aniket Sahrawat May 08 '21 at 08:52
  • @AniketSahrawat Yes. But still the result of that is different from invoking `rangeClosed(0, Integer.MAX_VALUE)` (which would have worked without exception). My question was more inclined towards why one method was not calling the other in terms of implementation. – Gautham M May 08 '21 at 08:56