## Introduction

In this tutorial, we'll take a look at *how to generate random integers in a specific range in Java*.

We'll be taking a look at several approaches, including core Java and third-party solutions:

- Random.ints()
- Random.nextInt()
- Math.random()
- SecureRandom.nextInt()
- ThreadLocalRandom.nextInt()
- SplittableRandom.ints()

**Note:** For each approach, we'll cover *how to generate one random integer* as well as *how to generate a sequence of random integers*.

All of these methods are *lower-bound inclusive*, and *upper-bound exclusive*.

## Random.ints()

We're starting off with `Random.ints()`

which was added to the `Random`

class in Java 8, exactly for this purpose. Java originally didn't have a fully *intuitive* solution for this task, built-in.

The `ints()`

method returns a sequence of random values, in the form of an `IntStream`

. Being a `Stream`

implementation, it's unbounded:

```
Random random = new Random();
random.ints().forEach(System.out::println);
```

This results in:

```
-526320702
-744603161
474879020
1864311422
406782252
...
```

This is an unbounded `IntStream`

, which will generate any value from `Integer.MIN_VALUE`

to `Integer.MAX_VALUE`

. However, you *can specify a range*, as well as the number of elements you'd like to generate.

Additionally, the first argument is the number of elements you'd like to generate - otherwise, the stream will be generate an unlimited number of elements, until your Heap Memory space runs out:

```
List<Integer> intList = new Random().ints(5, 1, 11)
.boxed()
.collect(Collectors.toList());
System.out.println(intList);
```

Before collecting the `IntStream`

, we'll have to box it via the `boxed()`

method, which returns a stream consisting of the elements of the `IntStream`

, boxed to an `Integer`

. Then, we run `collect()`

on the returned stream - not the original one.

The `collect()`

method of the `IntStream`

doesn't return a collection - it runs a mutable reduction operation.

Running this code results in:

```
[1, 9, 9, 6, 2]
```

To generate a single random integer, you can simply tweak the first argument of the `ints()`

method, or use the `findFirst()`

and `getAsInt()`

methods to extract it from the `IntStream`

:

```
int randomInt = new Random().ints(1, 1, 11).findFirst().getAsInt();
System.out.println(randomInt);
```

This results in a random integer in the range between `1..10`

(second argument is exclusive):

```
5
```

## Random.nextInt()

A more classic example that you'll often see people using is simply utilizing the `Random.nextInt()`

method. It accepts a `bound`

parameter, which sets the *upper bound*, and sets the *lower bound* to `0`

by default.

Unfortunately, it doesn't allow you to change this - so a quick and simple "hack" can be used to specify the boundaries:

```
int min = 10;
int max = 100;
System.out.println(new Random().nextInt(max - min) + min);
```

This results in a random integer in the range between `min`

and `max`

:

```
53
```

Generating a sequence of this would require us to call the method multiple times:

```
public static List<Integer> intsInRange(int size, int lowerBound, int upperBound) {
Random random = new Random();
List<Integer> result = new ArrayList<>();
for (int i = 0; i < size; i++) {
result.add(random.nextInt(upperBound - lowerBound) + lowerBound);
}
return result;
}
```

This is a `List`

-limited recreation of the `Random.ints()`

functionality, which simply returns a list of randomly generated integers in a range, with a given size:

```
List<Integer> integerList = intsInRange(5, 0, 10);
System.out.println(integerList);
```

Running this code would result in something along the lines of:

```
[3, 8, 2, 2, 9]
```

## SecureRandom.nextInt()

The `SecureRandom`

class is an alternative to the classic `Random`

class, but provides a *cryptographically strong* random number generator. `Random`

internally relies on the *system's clock* to generate number seeds, which isn't *truly* random.

On the other hand, `SecureRandom`

takes much more random data from the environment to generate a much more random seed.

If cryptographic safety is a thing you're concerned with, you may opt to use `SecureRandom`

instead - which behaves in much the same way as `Random`

from the developer's point of view:

```
int max = 100;
int min = 10;
int randomInt = new SecureRandom().nextInt(max - min) + min;
System.out.println(randomInt);
```

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually *learn* it!

Which results in a random integer in the range between `min`

and `max`

:

```
95
```

And if you'd like to generate sequences, a helper method can be crafted:

```
public static List<Integer> intsInRange(int size, int lowerBound, int upperBound) {
SecureRandom random = new SecureRandom();
List<Integer> result = new ArrayList<>();
for (int i = 0; i < size; i++) {
result.add(random.nextInt(upperBound - lowerBound) + lowerBound);
}
return result;
}
```

Which you can use as:

```
List<Integer> integerList = intsInRange3(5, 0, 10);
System.out.println(integerList);
```

And which results in:

```
[0, 9, 5, 6, 5]
```

## Math.random()

The `Math`

class provides us with great math-related helper methods. One of them is the `Math.random()`

method, which returns a random value between `0..1`

. Typically, it's used to generate random percentile values.

However, in a similar vein to the `Random.nextInt()`

hack - you can utilize this functionality to generate any integer in a certain range:

```
int min = 10;
int max = 100;
int randomNumber = (int)(Math.random() * (max + 1 - min) + min);
System.out.println(randomNumber);
```

Though, this one is even less intuitive than the previous approach. Running this code results in something along the lines of:

```
43
```

If you'd like to work with a sequence, we'd create a helper method to append each generated value to a list:

```
public static List<Integer> intsInRange(int size, int lowerBound, int upperBound) {
List<Integer> result = new ArrayList<>();
for (int i = 0; i < size; i++) {
result.add((int)(Math.random() * (upperBound + 1 - lowerBound) + lowerBound));
}
return result;
}
```

And then we can call it as:

```
List<Integer> integerList = intsInRange(5, 0, 10);
System.out.println(integerList);
```

Which produces:

```
[9, 0, 3, 2, 0]
```

## ThreadLocalRandom.nextInt()

If you're working in a multi-threaded environment, the `ThreadLocalRandom`

class is meant to be used as a thread-safe equivalent to `Random`

. Fortunately, it *does* offer a `nextInt()`

method with *both* an upper and lower bound:

```
int randomInt = ThreadLocalRandom.current().nextInt(0, 10);
System.out.println(randomInt);
```

As usual, the lower bound is included, while the upper bound isn't:

```
3
```

Similarly, you can create a helper function to generate a sequence of these:

```
public static List<Integer> intsInRange(int size, int lowerBound, int upperBound) {
List<Integer> result = new ArrayList<>();
for (int i = 0; i < size; i++) {
result.add(ThreadLocalRandom.current().nextInt(lowerBound, upperBound));
}
return result;
}
```

Which you can use as:

```
List<Integer> integerList = intsInRange4(5, 0, 10);
System.out.println(integerList);
```

```
[1, 9, 1, 9, 7]
```

## SplittableRandom.ints()

A less-known class in the Java API is the `SplittableRandom`

class - which is used as a generator of pseudo-random values. As the name implies, it's splittable and runs in parallel, and is really only used when you have tasks that could split again into smaller sub-tasks.

It's worth noting that this class is also based on non-secure seed generation - if you're looking for a safe seed generation, use `SecureRandom`

.

The class offers an `ints()`

method, which from our perspective, works in the same way as `Random.ints()`

:

```
List<Integer> intList = new SplittableRandom().ints(5, 1, 11)
.boxed()
.collect(Collectors.toList());
System.out.println(intList);
```

Which results in:

```
[3, 2, 8, 10, 3]
```

And, if you'd like to generate only one random number, you can ditch the collector and use `findFirst()`

with `getAsInt()`

:

```
int randomInt = new SplittableRandom().ints(1, 1, 11).findFirst().getAsInt();
System.out.println(randomInt);
```

Which results in:

```
4
```

## Conclusion

In this tutorial, we've taken an exhaustive look at *how to generate random integers in range in Java*.

We've gone over the newest and most useful method, as well as some other popular methods of finishing this task. Most of the approaches rely on the `Random`

or `Random`

-equivalent classes, used for more specific contexts.