#java #java-8 #java-stream
Вопрос:
IntStream.range(x,y)
вернет поток из x(включительно) и y(эксклюзивно). IntStream.rangeClosed(x,y)
вернет поток из x(включительно) и y(включительно).
Я ожидал rangeClosed(x,y)
, что вызову range(x,y-1)
или range(x,y)
вызову rangeClosed(x,y-1)
. Но при взгляде на исходный код для range
этого было похоже:
if (startInclusive >= endExclusive) {
return empty();
} else {
return StreamSupport.intStream(
new Streams.RangeIntSpliterator(startInclusive, endExclusive, false /*not closed*/), false);
}
У rangeClosed
него также была очень похожая реализация, а не range(x,y 1)
. Единственная разница заключалась в том, что третий аргумент to Streams.RangeIntSpliterator
true
вместо false
обозначения того, что диапазон закрыт.
Это логическое значение затем используется для инициализации int last
поля в Streams.RangeIntSpliterator
классе, и против него упоминается приведенный ниже комментарий:
1, если диапазон закрыт и последний элемент не был пройден в противном случае, 0, если диапазон открыт или является закрытым диапазоном и все элементы были пройдены
Почему необходима такая реализация, а range
не просто вызов rangeClosed
или наоборот? Есть ли какая-то существенная разница между вызовом rangeClosed(x,y)
вместо range(x,y 1)
?
Ответ №1:
Несмотря на то, что в обычном сценарии нет никаких различий, это вызовет проблему, если входные данные для методов будут иметь минимальные/максимальные пределы Integer
.
Предполагая, что rangeClosed(x,y)
это вызывает range(x,y 1)
. Если вы вызываете rangeClosed(0, Integer.MAX_VALUE)
, то вместо ожидаемого числа итераций (2147483648) фактическое число итераций будет равно 0, что Integer.MAX_VALUE 1
приведет к переполнению и будет возвращен пустой поток.
Подобное переполнение приведет к тому, что результат будет отличаться в случае, если входные данные будут Integer.MIN_VALUE
.
Комментарии:
1. Интервалы открытия и закрытия представлены с помощью
(open, close]
. Обратите внимание, чтоMath.addExact(y, 1)
это быстро приведет к сбою и должно использоваться в идеале.2. @AniketSahrawat Извините, но я не могу понять, что вы пытались донести. Похоже ли это на то, что
range(x , Math.addExact(y, 1))
приведет к исключению, а не к неправильному результату по сравнению с темrange(x, y 1)
, когдаy
этоMAX_VALUE
произойдет ?3. Да, действительно. Попробуйте
range(0 , Math.addExact(Integer.MAX_VALUE, 1))
, это приведет к исключению.4. @AniketSahrawat Да. Но все равно результат этого отличается от вызова
rangeClosed(0, Integer.MAX_VALUE)
(который работал бы без исключения). Мой вопрос был более склонен к тому, почему один метод не вызывал другой с точки зрения реализации.