# Random Number Generation in Java

0 CommentsLast Updated on October 15, 2024 by jt

While developing applications, we often need to generate random numbers. Java provides support to generate random numbers primarily through the java.lang.Math and java.util.Random classes. Java also has the ability to generate secure random with java.security.SecureRandom, and random numbers isolated to the current thread with java.util.concurrent.ThreadLocalRandom.

You can use the `java.util.Random`

class to generate random numbers of different types, such as `int`

, `float`

, `double`

, `long`

, and `boolean`

.

To generate random numbers, first, create an instance of the `Random`

class and then call one of the random value generator methods, such as `nextInt()`

, `nextDouble()`

, or `nextLong()`

.

The `nextInt()`

method of `Random`

accepts a bound integer and returns a random integer from 0 (inclusive) to the specified bound (exclusive).

In addition to `java.util.Random`

, Java offers several other approaches for generating random numbers, each suited for different needs:

**Math.random()**: This method generates a `double`

value, utilizing the `Random`

class internally. It’s a simpler option for basic needs without the need to instantiate a class.

**java.security.SecureRandom**: For applications requiring a cryptographically strong random number generator, `SecureRandom`

is the go-to class. While it provides enhanced security, it’s generally slower, so consider your application’s performance needs when choosing this option.

**java.util.concurrent.ThreadLocalRandom**: Introduced in Java 1.7, this class is ideal for generating random numbers in multithreaded environments. It offers methods similar to `Random`

but with better performance in concurrent applications.

## Random Number Generation using the Random Class

You can use the `java.util.Random`

class to generate random numbers of different types, such as `int`

, `float`

, `double`

, `long`

, and `boolean`

.

To generate random numbers, first, create an instance of the Random class and then call one of the random value generator methods, such as `nextInt()`

, `nextDouble()`

, or `nextLong().`

The `nextInt()`

method of `Random`

accepts a bound integer and returns a random integer from 0 (inclusive) to the specified bound (exclusive).

The code to use the `nextInt()`

method is this.

```
public static int generateRandomInt(int upperRange){
Random random = new Random();
return random.nextInt(upperRange);
}
```

The code to use the `nextInt()`

method to generate an integer within a range is this.

```
public static int generateRandomIntIntRange(int min, int max) {
Random r = new Random();
return r.nextInt((max - min) + 1) + min;
}
```

The `nextFloat()`

and `nextDouble()`

methods allow generating float and double values between `0.0`

and `1.0`

.

The code to use both the methods is this.

```
public static double generateRandomDouble(){
Random random = new Random();
return random.nextDouble();
}
public static float generateRandomFloat(){
Random random = new Random();
return random.nextFloat();
}
```

## New Random Number Generation Features in Java 8

Java 8 has introduced a new method `ints()`

in the `java.util.Random`

class. The `ints()`

method returns an unlimited stream of pseudorandom `int`

values. You can limit the random numbers between a specified range by providing the minimum and the maximum values.

The code to use the `Random.ints()`

method to generate random integer values within a specified range is this.

```
public static int getRandomNumberInts(int min, int max){
Random random = new Random();
return random.ints(min,(max+1)).findFirst().getAsInt();
}
```

The `getRandomNumberInts()`

method generates a stream of random integers between the `min`

(inclusive) and `max`

(exclusive). As `ints()`

method produces an `IntStream`

, the code calls the `findFirst()`

method that returns an `OptionalInt`

object that describes the first element of this stream. The code then calls the `getAsInt() `

method to return the `int`

value in `OptionalInt`

.

The code to use the `Random.ints()`

method to generate a stream of specified random integer values is this.

```
public static void getStreamOfRandomInts(int num) {
Random random = new Random();
random.ints(num).sorted().forEach(System.out::println);
}
```

The code to call the preceding method is this.

```
System.out.println("Random int stream: RandomIntStreamofSize = ");
RandomDemo.getStreamOfRandomInts(5);
```

The output of the preceding code is this.

```
Random int stream: RandomIntStreamofSize =
-1861317227
-1205557317
453883217
762357682
1725970934
```

The code to use the `Random.ints()`

method to generate a stream of a specified number of random integer values between a range is this.

```
public static void getStreamOfRandomIntsWithRange(int num, int min, int max) {
Random random = new Random();
random.ints(num,min, max).sorted().forEach(System.out::println);
}
```

The code to call the preceding method is this.

```
System.out.println("Random int stream of specified size in range: RandomIntStreamofSizeInRange = ");
RandomDemo.getStreamOfRandomIntsWithRange(5,0,10);
```

The output of the preceding code is this.

```
Random int stream of specified size in range: RandomIntStreamofSizeInRange =
2
2
3
4
6
```

In addition to `ints()`

, some other frequently used methods that Java 8 introduces to the `Random`

class which can return a sequential stream of random numbers are:

`LongStream longs()`

`DoubleStream doubles()`

## Random Numbers using the Math Class

Java provides the `Math`

class in the `java.util`

package to generate random numbers.

The `Math`

class contains the static `Math.random()`

method to generate random numbers of `double`

type.

The `random()`

method returns a `double`

value with a positive sign, greater than or equal to `0.0`

and less than `1.0`

. When you call `Math.random()`

, under the hood, a `java.util.Random`

pseudorandom-number generator object is created and used.

You can use the `Math.random()`

method with or without passing parameters. If you provide parameters, the method produces random numbers within the given parameters.

The code to use the `Math.random()`

method is this.

```
public static double getRandomNumber(){
double x = Math.random();
return x;
}
```

The `getRandomNumber()`

method uses the `Math.random()`

method to return a positive double value, that is greater than or equal to `0.0`

and less than `1.0`

.

The output of running the code is this.

`Double between 0.0 and 1.0: SimpleRandomNumber = 0.21753313144345698`

### Random Numbers within a Given Range

For generating random numbers between a given a range, you need to specify the range. A standard expression for accomplishing this is:

`(Math.random() * ((max - min) + 1)) + min`

Let us break this expression into steps:

- First, multiply the magnitude of the range of values you want to cover by the result that
`Math.random()`

produces.`Math.random() * ( max - min )`

This returns a value in the range`[0, max – min]`

where`max`

is excluded. For example, if you want`[5,10]`

you need to cover`5`

integer values. So you can use`Math.random()*5`

. This would return a value in the range`[0,5]`

, where`5`

is not included. - Next, shift this range up to the range that you are targeting. You do this by adding the min value.

- First, multiply the magnitude of the range of values you want to cover by the result that

`(Math.random() * ( max - min )) + min`

But, this still does not include the maximum value.

To get the max value included, you need to add `1`

to your range parameter `(max - min)`

. This will return a random double within the specified range.

double x = (Math.random()*((max-min)+1))+min;

#### Random Double within a Given Range

There are different ways of implementing the above expression. Let us look at a couple of them.

By default, the `Math.random()`

method returns a random number of the type `double`

whenever it is called. The code to generate a random double value between a specified range is this.

```
public static double getRandomDoubleBetweenRange(double min, double max){
double x = (Math.random()*((max-min)+1))+min;
return x;
}
```

You can call the preceding method from the main method by passing the arguments like this.

`System.out.println("Double between 5.0 and 10.00: RandomDoubleNumber = "+getRandomDoubleBetweenRange(5.0, 10.00));`

The output is this.

`Double between 5.0 and 10.00: RandomDoubleNumber = 8.965219704004642`

#### Random Integer within a Given Range

The code to generate a random integer value between a specified range is this.

```
public static double getRandomIntegerBetweenRange(double min, double max){
double x = (int)(Math.random()*((max-min)+1))+min;
return x;
}
```

The preceding `getRandomIntegerBetweenRange()`

method produces a random integer between the given range. As `Math.random()`

method generates random numbers of double type, you need to truncate the decimal part and cast it to `int`

in order to get the integer random number. You can call this method from the main method by passing the arguments as follow:

`System.out.println("Integer between 2 and 6: RandomIntegerNumber = "+getRandomIntegerBetweenRange(2,6));`

The output is this.

`Integer between 2 and 6: RandomIntegerNumber = 5`

Note: You can pass a range of negative values to generate a random negative number within the range.

## Understanding SecureRandom in Java

In Java, **SecureRandom** is a class that provides a robust mechanism for generating random numbers with enhanced security. It is part of the `java.security`

package, which focuses on cryptographically secure elements. Here’s how SecureRandom stands out from other random number generators:

### Key Features of SecureRandom

**Cryptographic Security**: Unlike`java.util.Random`

, which is designed for simplicity and speed, SecureRandom is built to meet the stringent requirements of cryptographic applications. Which means it’s suitable for tasks where the predictability of random numbers could lead to vulnerabilities.**Provider Flexibility**: SecureRandom allows you to specify different algorithms through various security providers. This flexibility makes it adaptable to a range of security levels and compliance needs.**Strong Initialization**: SecureRandom can be seeded with unpredictable data from the system environment, making it less susceptible to attacks that exploit predictable seed values.

### Why Choose SecureRandom Over Random?

**Predictability**: The`Random`

class uses a linear congruential generator, which, if the seed is known, can make subsequent values predictable. In contrast, SecureRandom’s algorithms, like SHA1PRNG or NativePRNG, are designed to resist prediction.**Regulatory Compliance**: Many security protocols and standards require the use of cryptographically secure random number generation, which SecureRandom provides, thus ensuring compliance.

### Example Usage

Let’s take a moment to see how you can implement SecureRandom in your Java programs:

```
import java.security.SecureRandom;
public class SecureRandomExample {
public static void main(String[] args) {
SecureRandom secureRandom = new SecureRandom();
int secureRand = secureRandom.nextInt();
System.out.println("Secure Random Number: " + secureRand);
}
}
```

### Generating Random Numbers in a Multithreaded Environment with ThreadLocalRandom

When working with multithreaded applications, generating random numbers efficiently and safely is crucial. ThreadLocalRandom is a class in Java that serves this purpose perfectly. It avoids the contention that can occur with using a single Random instance across multiple threads.

#### Using ThreadLocalRandom

First we can create a Runnable Task as follows:

```
import java.util.concurrent.ThreadLocalRandom;
class RandomNumberTask implements Runnable {
@Override
public void run() {
String threadName = Thread.currentThread().getName();
int randomNumber = ThreadLocalRandom.current().nextInt();
System.out.println(threadName + ":: Random Number: " + randomNumber);
}
}
```

We can now run our ThreadLocalRandom task in multiple threads as follows:

```
public static void main(String[] args) {
Runnable task = new RandomNumberTask();
for (int i = 0; i < 5; i++) {
Thread thread = new Thread(task);
thread.setName("Thread-" + i);
thread.start();
}
}
```

This will produce the following output:

```
Thread-3:: Random Number: -1153038614
Thread-4:: Random Number: -184851317
Thread-0:: Random Number: 581582528
Thread-2:: Random Number: -231021620
Thread-1:: Random Number: 788777395
```

We can also use `ThreadLocalRandom`

to generate numbers in a range. If we make the following change, ThreadLocalRandom will generate random numbers between 1 and 10.

```
int randomNumber = ThreadLocalRandom.current().nextInt(1, 10);
```

With the range supplied to `nextInt()`

(inclusive), the following output is generated:

```
Thread-0:: Random Number: 1
Thread-2:: Random Number: 5
Thread-4:: Random Number: 6
Thread-3:: Random Number: 2
Thread-1:: Random Number: 2
```

#### Advantages of Using ThreadLocalRandom

**Concurrency Efficiency:**Each thread gets its own instance, minimizing contention and maximizing performance in multithreaded scenarios.**Convenience Methods:**Offers additional methods to generate random values within a specified range.**Simplified Syntax:**Makes it easier to create random numbers compared to other methods like`Random`

.

By incorporating `ThreadLocalRandom`

into your multithreaded programs, you can achieve efficient and thread-safe random number generation. This approach ensures that each thread operates independently, eliminating common pitfalls such as concurrency issues.

## Summary

As you can see, the Java language offers a number of different options for random number generation. Each option has its own benefits and use cases. Using `java.util.Random`

will cover most use cases. However, when needed, you have can use the other options described in this post.