There are several uses for IntStream.range.

One is to use the int values themselves:

IntStream.range(start, end).filter(i -> isPrime(i))....

Another is to do something N times:

IntStream.range(0, N).forEach(this::doSomething);

Your case (1) is to create an array filled with a range:

int[] arr = IntStream.range(start, end).toArray();

You say this is "very slow" but, like other respondents, I suspect your benchmark methodology. For small arrays there is indeed more overhead with stream setup, but this should be so small as to be unnoticeable. For large arrays the overhead should be negligible, as filling a large array is dominated by memory bandwidth.

Sometimes you need to fill an existing array. You can do that this way:

int[] arr = new int[end - start];
IntStream.range(0, end - start).forEach(i -> arr[i] = i + start);

There's a utility method Arrays.setAll that can do this even more concisely:

int[] arr = new int[end - start];
Arrays.setAll(arr, i -> i + start);

There is also Arrays.parallelSetAll which can fill an existing array in parallel. Internally, it simply uses an IntStream and calls parallel() on it. This should provide a speedup for large array on a multicore system.

I've found that a fair number of my answers on Stack Overflow involve using IntStream.range. You can search for them using these search criteria in the search box:

user:1441122 IntStream.range

One application of IntStream.range I find particularly useful is to operate on elements of an array, where the array indexes as well as the array's values participate in the computation. There's a whole class of problems like this.

For example, suppose you want to find the locations of increasing runs of numbers within an array. The result is an array of indexes into the first array, where each index points to the start of a run.

To compute this, observe that a run starts at a location where the value is less than the previous value. (A run also starts at location 0). Thus:

    int[] arr = { 1, 3, 5, 7, 9, 2, 4, 6, 3, 5, 0 };
    int[] runs = IntStream.range(0, arr.length)
                          .filter(i -> i == 0 || arr[i-1] > arr[i])
                          .toArray();
    System.out.println(Arrays.toString(runs));

    [0, 5, 8, 10]

Of course, you could do this with a for-loop, but I find that using IntStream is preferable in many cases. For example, it's easy to store an unknown number of results into an array using toArray(), whereas with a for-loop you have to handle copying and resizing, which distracts from the core logic of the loop.

Finally, it's much easier to run IntStream.range computations in parallel.

Answer from Stuart Marks on Stack Overflow
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › util › stream › IntStream.html
IntStream (Java Platform SE 8 )
2 weeks ago - static IntStream range(int startInclusive, int endExclusive) Returns a sequential ordered IntStream from startInclusive (inclusive) to endExclusive (exclusive) by an incremental step of 1. API Note: An equivalent sequence of increasing values can be produced sequentially using a for loop as ...
Top answer
1 of 8
50

There are several uses for IntStream.range.

One is to use the int values themselves:

IntStream.range(start, end).filter(i -> isPrime(i))....

Another is to do something N times:

IntStream.range(0, N).forEach(this::doSomething);

Your case (1) is to create an array filled with a range:

int[] arr = IntStream.range(start, end).toArray();

You say this is "very slow" but, like other respondents, I suspect your benchmark methodology. For small arrays there is indeed more overhead with stream setup, but this should be so small as to be unnoticeable. For large arrays the overhead should be negligible, as filling a large array is dominated by memory bandwidth.

Sometimes you need to fill an existing array. You can do that this way:

int[] arr = new int[end - start];
IntStream.range(0, end - start).forEach(i -> arr[i] = i + start);

There's a utility method Arrays.setAll that can do this even more concisely:

int[] arr = new int[end - start];
Arrays.setAll(arr, i -> i + start);

There is also Arrays.parallelSetAll which can fill an existing array in parallel. Internally, it simply uses an IntStream and calls parallel() on it. This should provide a speedup for large array on a multicore system.

I've found that a fair number of my answers on Stack Overflow involve using IntStream.range. You can search for them using these search criteria in the search box:

user:1441122 IntStream.range

One application of IntStream.range I find particularly useful is to operate on elements of an array, where the array indexes as well as the array's values participate in the computation. There's a whole class of problems like this.

For example, suppose you want to find the locations of increasing runs of numbers within an array. The result is an array of indexes into the first array, where each index points to the start of a run.

To compute this, observe that a run starts at a location where the value is less than the previous value. (A run also starts at location 0). Thus:

    int[] arr = { 1, 3, 5, 7, 9, 2, 4, 6, 3, 5, 0 };
    int[] runs = IntStream.range(0, arr.length)
                          .filter(i -> i == 0 || arr[i-1] > arr[i])
                          .toArray();
    System.out.println(Arrays.toString(runs));

    [0, 5, 8, 10]

Of course, you could do this with a for-loop, but I find that using IntStream is preferable in many cases. For example, it's easy to store an unknown number of results into an array using toArray(), whereas with a for-loop you have to handle copying and resizing, which distracts from the core logic of the loop.

Finally, it's much easier to run IntStream.range computations in parallel.

2 of 8
7

Here's an example:

public class Test {

    public static void main(String[] args) {
        System.out.println(sum(LongStream.of(40,2))); // call A
        System.out.println(sum(LongStream.range(1,100_000_000))); //call B
    }

    public static long sum(LongStream in) {
        return in.sum();
    }

}

So, let's look at what sum() does: it counts the sum of an arbitrary stream of numbers. We call it in two different ways: once with an explicit list of numbers, and once with a range.

If you only had call A, you might be tempted to put the two numbers into an array and pass it to sum() but that's clearly not an option with call B (you'd run out of memory). Likewise you could just pass the start and end for call B, but then you couldn't support the case of call A.

So to sum it up, ranges are useful here because:

  • We need to pass them around between methods
  • The target method doesn't just work on ranges but any stream of numbers
  • But it only operates on individual numbers of the stream, reading them sequentially. (This is why shuffling with streams is a terrible idea in general.)

There is also the readability argument: code using streams can be much more concise than loops, and thus more readable, but I wanted to show an example where a solution relying on IntStreans is functionally superior too.

I used LongStream to emphasise the point, but the same goes for IntStream

And yes, for simple summing this may look like a bit of an overkill, but consider for example reservoir sampling

🌐
GeeksforGeeks
geeksforgeeks.org › java › intstream-range-java
IntStream range() in Java - GeeksforGeeks
December 6, 2018 - IntStream range(int startInclusive, int endExclusive) returns a sequential ordered IntStream from startInclusive (inclusive) to endExclusive (exclusive) by an incremental step of 1.
🌐
Baeldung
baeldung.com › home › java › java streams › understanding the difference between stream.of() and intstream.range()
Understanding the Difference Between Stream.of() and IntStream.range() | Baeldung
March 7, 2025 - On the other hand, IntStream.range() returns a sequentially-ordered IntStream. That’s to say, the input of the IntStream object is already sorted. Furthermore, when it sorts an already sorted input, Java applies the optimization to make the ...
🌐
Oracle
docs.oracle.com › en › java › javase › 21 › docs › api › java.base › java › util › stream › IntStream.html
IntStream (Java SE 21 & JDK 21)
January 20, 2026 - static IntStream range · (int startInclusive, int endExclusive) Returns a sequential ordered IntStream from startInclusive (inclusive) to endExclusive (exclusive) by an incremental step of 1. API Note: An equivalent sequence of increasing values can be produced sequentially using a for loop ...
🌐
JavaBrahman
javabrahman.com › java-8 › java-8-how-to-use-range-rangeclosed-methods-of-intstream-longstream-with-examples
Java 8 - How to use range(), rangeClosed() methods of IntStream, LongStream with examples - JavaBrahman
Difference between range() and rangeClosed() methods range() method generates a stream of numbers starting from start value but stops before reaching the end value, i.e start value is inclusive and end value is exclusive.
🌐
Medium
neesri.medium.com › primitive-type-in-stream-java-8-fb587f5c1e5b
Mastering IntStream in Java 8. In Java 8 and later versions, the… | by A cup of JAVA coffee with NeeSri | Medium
July 20, 2025 - List<Integer> numbersList = Arrays.asList(1, 2, 3, 4, 5); IntStream intStream = numbersList.stream().mapToInt(Integer::intValue); 2. Creating a primitive stream using range and rangeClosed methods: IntStream intRange = IntStream.range(1, 5); // 1, 2, 3, 4 IntStream intRangeClosed = IntStream.rangeClosed(1, 5); // 1, 2, 3, 4, 5 ·
🌐
Blogger
javarevisited.blogspot.com › 2021 › 05 › java-8-intstream-examples-range-sum-rangeclosed-max.html
How to use Stream range, rangeClosed, sum and sorted methods? Java 8 IntStream Examples -
April 3, 2023 - You can create IntStream of specific values by using IntStream.of() static factory method, or you can convert any stream to IntStream by using the mapToInt() function, which is extremely useful to convert numeric String into primitive int and then performing these aggregate and grouping operations. Stream API also provides a couple of utility method to create a sequence of string in a specific range like IntStream.range(strat, endExclusive) and IntStream.rangeClosed(start, endInclusive) can be used to create a sequence of integers incremented by 1 like range(1, 5) will produce 1, 2, 3, 4 because last value is exclusive, while rangeClosed(1, 5) will produce 1, 2, 3, 4, 5.
Find elsewhere
🌐
Tabnine
tabnine.com › home page › code › java › java.util.stream.intstream
java.util.stream.IntStream.range java code examples | Tabnine
@Override public void getNextTarget(Tensor target) { IntStream stream = IntStream.range(0, currentArrays.size()); if (properties.getParallelPreprocessing()) { stream = stream.parallel(); } stream.forEach(i -> { float[] t = getNextTarget(augmentedToRaw.get(arrayToAugmented.get(currentArrays.get(i)))); if (t != null) { System.arraycopy(t, 0, target.getElements(), target.getStartIndex() + i * getTargetDimensions(), t.length); } }); }
🌐
TutorialsPoint
tutorialspoint.com › intstream-range-method-in-java
IntStream range() method in Java
July 30, 2019 - The range() method in the IntStream class in Java is used to return a sequential ordered IntStream from startInclusive to endExclusive by an incremental step of 1. This includes the startInclusive as well. The syntax is as follows −
🌐
Dot Net Perls
dotnetperls.com › range-java
Java - IntStream.range Example - Dot Net Perls
Range() is a useful method. We can create a Stream and then operate upon it with IntStream-based methods like filter().
🌐
Oracle
docs.oracle.com › en › java › javase › 11 › docs › api › java.base › java › util › stream › IntStream.html
IntStream (Java SE 11 & JDK 11 )
January 20, 2026 - static IntStream range​(int startInclusive, int endExclusive) Returns a sequential ordered IntStream from startInclusive (inclusive) to endExclusive (exclusive) by an incremental step of 1. API Note: An equivalent sequence of increasing values can be produced sequentially using a for loop ...
🌐
The Canny Coder
thecannycoder.wordpress.com › 2014 › 06 › 29 › ranges-and-looping-with-intstream
Ranges and Looping with IntStream | The Canny Coder
July 2, 2014 - The difference is that rangeClosed has an inclusive endpoint where are range does not. There is no version yet with a step or descending values – the pipeline is initialised as empty if the start is beyond the last element. If we wanted a step, we use transformations with map: IntStream.rangeClosed(1, 5).map(x -> 6-x) .forEach(System.out::println);
🌐
Java Code Geeks
javacodegeeks.com › home › core java
Exploring Java 8 IntStream: Practical Examples and Usage - Java Code Geeks
February 9, 2024 - When working with IntStream in Java, it’s essential to adhere to best practices and leverage tips to ensure efficient and readable code. Firstly, prefer using the range method for generating sequential ranges of integers. Employ method chaining to create concise and readable pipelines of operations.
🌐
Oracle
docs.oracle.com › javase › 10 › docs › api › java › util › stream › IntStream.html
IntStream (Java SE 10 & JDK 10 )
static IntStream range​(int startInclusive, int endExclusive) Returns a sequential ordered IntStream from startInclusive (inclusive) to endExclusive (exclusive) by an incremental step of 1. API Note: An equivalent sequence of increasing values can be produced sequentially using a for loop ...
🌐
Java Code Geeks
javacodegeeks.com › home › core java
Java 8 IntStream With Working Examples - Java Code Geeks
January 3, 2022 - IntStream of(int… values) – Returns a stream with all the components supplied. range() is used to generate the numbers in the order with incremental by one.
🌐
HowToDoInJava
howtodoinjava.com › home › java 8 › guide to intstream in java
Guide to IntStream in Java - HowToDoInJava
March 4, 2022 - The IntStream produced by range() methods is a sequential ordered stream of int values which is the equivalent sequence of increasing int values in a for-loop and value incremented by 1.
🌐
Oracle
docs.oracle.com › en › java › javase › 17 › docs › api › java.base › java › util › stream › IntStream.html
IntStream (Java SE 17 & JDK 17)
January 20, 2026 - static IntStream range · (int startInclusive, int endExclusive) Returns a sequential ordered IntStream from startInclusive (inclusive) to endExclusive (exclusive) by an incremental step of 1. API Note: An equivalent sequence of increasing values can be produced sequentially using a for loop ...