Here the code for a Simple random generator:

public class SimpleRandom {
/**
 * Test code
 */
public static void main(String[] args) {
    SimpleRandom rand = new SimpleRandom(10);
    for (int i = 0; i < 25; i++) {
        System.out.println(rand.nextInt());
    }

}

private int max;
private int last;

// constructor that takes the max int
public SimpleRandom(int max){
    this.max = max;
    last = (int) (System.currentTimeMillis() % max);
}

// Note that the result can not be bigger then 32749
public int nextInt(){
    last = (last * 32719 + 3) % 32749;
    return last % max;
}
}

The code above is a "Linear congruential generator (LCG)", you can find a good description of how it works here.

Disclamer:

The code above is designed to be used for research only, and not as a replacement to the stock Random or SecureRandom.

Answer from Frank on Stack Overflow
๐ŸŒ
Coderanch
coderanch.com โ€บ t โ€บ 658371 โ€บ java โ€บ alternative-method-replace-math-random
Looking for alternative method to replace math.random and random function in java (Java in General forum at Coderanch)
November 25, 2015 - Winston linked it here the other day: http://xorshift.di.unimi.it/ In short, it recommends xorshift1024*, xorshift128+ or SplitMix64, depending on the state space that you need. xorshift128+ is quite easy to implement in Java, as it only requires two long fields.
Discussions

Do you guys use Math.random() or the Random class more often for generating random numbers?
I always use Random. The reason is that if a class depends on random number generation, it actually has a dependency on another thing whose job it is to generate random numbers (you could even make the argument this is a hidden I/O operation). It's damn near impossible to write a unit test against a class or method that calls a global function because you have no access to mock out the response for that function within a test. This is even more the case for classes that rely on randomly generated numbers. Passing a Random into a class that needs access to random numbers makes it easy to unit-test that class, as well as substitute in alternative RNG as needed, for example using SecureRandom which implements the Random interface, providing a more even distribution of generated numbers at the cost of speed. Random number generators, at least in Java, tend to mutate state internally - which is dangerous for multi-threaded programming. You want to minimize the amount of state mutation in a program to enable multi-threading, and Random turns the mutable state for random number generation to be scoped to an object rather than to the entire global space as Math.random() does. Other benefits of using Random over Math.random(): You can pass a single instance of Random into the first class that needs the ability, and pass the same instance around into lower classes as they require it as well. This means that, on your program runs, if you output the seed number somewhere like into a log or temporary file, you can seed your program with the same seed value and generate exactly the same behavior, deterministically. This makes debugging issues that arise in your program much easier. The Random interface is superior, allowing you to request random booleans, byte sequences, doubles, floats, longs, and ints. It also allows you to request a random int within a specific range. All of these let you avoid inserting the same boilerplate math that uses a Math.random(). More on reddit.com
๐ŸŒ r/java
18
6
October 10, 2012
java - Math.random() versus Random.nextInt(int) - Stack Overflow
Math.random() also requires about twice the processing and is subject to synchronization. More on stackoverflow.com
๐ŸŒ stackoverflow.com
how random is Math.random() in java across different jvms or different machines - Stack Overflow
Is there something that's better than Math.random() and performs just as good (not much worse at least)? ... Please have a look at the following link. coderanch.com/t/510167/java/java/Random-generator-failing More on stackoverflow.com
๐ŸŒ stackoverflow.com
How do I generate random integers within a specific range in Java? - Stack Overflow
The Math.Random class in Java is 0-based. More on stackoverflow.com
๐ŸŒ stackoverflow.com
Top answer
1 of 5
11
I always use Random. The reason is that if a class depends on random number generation, it actually has a dependency on another thing whose job it is to generate random numbers (you could even make the argument this is a hidden I/O operation). It's damn near impossible to write a unit test against a class or method that calls a global function because you have no access to mock out the response for that function within a test. This is even more the case for classes that rely on randomly generated numbers. Passing a Random into a class that needs access to random numbers makes it easy to unit-test that class, as well as substitute in alternative RNG as needed, for example using SecureRandom which implements the Random interface, providing a more even distribution of generated numbers at the cost of speed. Random number generators, at least in Java, tend to mutate state internally - which is dangerous for multi-threaded programming. You want to minimize the amount of state mutation in a program to enable multi-threading, and Random turns the mutable state for random number generation to be scoped to an object rather than to the entire global space as Math.random() does. Other benefits of using Random over Math.random(): You can pass a single instance of Random into the first class that needs the ability, and pass the same instance around into lower classes as they require it as well. This means that, on your program runs, if you output the seed number somewhere like into a log or temporary file, you can seed your program with the same seed value and generate exactly the same behavior, deterministically. This makes debugging issues that arise in your program much easier. The Random interface is superior, allowing you to request random booleans, byte sequences, doubles, floats, longs, and ints. It also allows you to request a random int within a specific range. All of these let you avoid inserting the same boilerplate math that uses a Math.random().
2 of 5
8
Under the hood Math.random() uses the Random class anyways. On the first call to it it initializes an instance of Random (this call is synchronized but as it is static it only happens once so this doesn"t really matter in practice). After that it keeps calling nextDouble() on this instance
Top answer
1 of 4
188

Here is the detailed explanation of why "Random.nextInt(n) is both more efficient and less biased than Math.random() * n" from the Sun forums post that Gili linked to:

Math.random() uses Random.nextDouble() internally.

Random.nextDouble() uses Random.next() twice to generate a double that has approximately uniformly distributed bits in its mantissa, so it is uniformly distributed in the range 0 to 1-(2^-53).

Random.nextInt(n) uses Random.next() less than twice on average- it uses it once, and if the value obtained is above the highest multiple of n below MAX_INT it tries again, otherwise is returns the value modulo n (this prevents the values above the highest multiple of n below MAX_INT skewing the distribution), so returning a value which is uniformly distributed in the range 0 to n-1.

Prior to scaling by 6, the output of Math.random() is one of 2^53 possible values drawn from a uniform distribution.

Scaling by 6 doesn't alter the number of possible values, and casting to an int then forces these values into one of six 'buckets' (0, 1, 2, 3, 4, 5), each bucket corresponding to ranges encompassing either 1501199875790165 or 1501199875790166 of the possible values (as 6 is not a disvisor of 2^53). This means that for a sufficient number of dice rolls (or a die with a sufficiently large number of sides), the die will show itself to be biased towards the larger buckets.

You will be waiting a very long time rolling dice for this effect to show up.

Math.random() also requires about twice the processing and is subject to synchronization.

2 of 4
28

another important point is that Random.nextInt(n) is repeatable since you can create two Random object with the same seed. This is not possible with Math.random().

๐ŸŒ
Oracle
docs.oracle.com โ€บ javase โ€บ 8 โ€บ docs โ€บ api โ€บ java โ€บ util โ€บ Random.html
Random (Java Platform SE 8 )
1 week ago - Java implementations must use all the algorithms shown here for the class Random, for the sake of absolute portability of Java code. However, subclasses of class Random are permitted to use other algorithms, so long as they adhere to the general contracts for all the methods. The algorithms implemented by class Random use a protected utility method that on each invocation can supply up to 32 pseudorandomly generated bits. Many applications will find the method Math.random() simpler to use.
๐ŸŒ
Java Mex
javamex.com โ€บ tutorials โ€บ random_numbers โ€บ generators_overview.shtml
Alternatives to java.util.Random
Out of the box, Java provides the following alternatives: ThreadLocalRandom is a fast, medium-quality random number generator with a period of 264 that passes many statistical tests (but whose algorithm isn't fixed in principle and could change in future Java versions);
Find elsewhere
Top answer
1 of 16
4401

Java 7+

In Java 1.7 or later, the standard way to do this (generate a basic non-cryptographically secure random integer in the range [min, max]) is as follows:

import java.util.concurrent.ThreadLocalRandom;

// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = ThreadLocalRandom.current().nextInt(min, max + 1);

See the relevant JavaDoc. This approach has the advantage of not needing to explicitly initialize a java.util.Random instance, which can be a source of confusion and error if used inappropriately.

However, conversely with ThreadLocalRandom there is no way to explicitly set the seed so it can be difficult to reproduce results in situations where that is useful such as testing or saving game states or similar.

Java 17+

As of Java 17, the psuedorandom number generating classes in the standard library implement the RandomGenerator interface. See the linked JavaDoc for more information. For example, if a cryptographically strong random number generator is desired, the SecureRandom class can be used.

Earlier Java

Before Java 1.7, the standard way to do this is as follows:

import java.util.Random;

/**
 * Returns a pseudo-random number between min and max, inclusive.
 * The difference between min and max can be at most
 * <code>Integer.MAX_VALUE - 1</code>.
 *
 * @param min Minimum value
 * @param max Maximum value.  Must be greater than min.
 * @return Integer between min and max, inclusive.
 * @see java.util.Random#nextInt(int)
 */
public static int randInt(int min, int max) {

    // NOTE: This will (intentionally) not run as written so that folks
    // copy-pasting have to think about how to initialize their
    // Random instance.  Initialization of the Random instance is outside
    // the main scope of the question, but some decent options are to have
    // a field that is initialized once and then re-used as needed or to
    // use ThreadLocalRandom (if using at least Java 1.7).
    // 
    // In particular, do NOT do 'Random rand = new Random()' here or you
    // will get not very good / not very random results.
    Random rand;

    // nextInt is normally exclusive of the top value,
    // so add 1 to make it inclusive
    int randomNum = rand.nextInt((max - min) + 1) + min;

    return randomNum;
}

See the relevant JavaDoc. In practice, the java.util.Random class is often preferable to java.lang.Math.random().

In particular, there is no need to reinvent the random integer generation wheel when there is a straightforward API within the standard library to accomplish the task.

2 of 16
1520

Note that this approach is more biased and less efficient than a nextInt approach, https://stackoverflow.com/a/738651/360211

One standard pattern for accomplishing this is:

Min + (int)(Math.random() * ((Max - Min) + 1))

The Java Math library function Math.random() generates a double value in the range [0,1). Notice this range does not include the 1.

In order to get a specific range of values first, you need to multiply by the magnitude of the range of values you want covered.

Math.random() * ( Max - Min )

This returns a value in the range [0,Max-Min), where 'Max-Min' is not included.

For example, if you want [5,10), you need to cover five integer values so you use

Math.random() * 5

This would return a value in the range [0,5), where 5 is not included.

Now you need to shift this range up to the range that you are targeting. You do this by adding the Min value.

Min + (Math.random() * (Max - Min))

You now will get a value in the range [Min,Max). Following our example, that means [5,10):

5 + (Math.random() * (10 - 5))

But, this still doesn't include Max and you are getting a double value. In order to get the Max value included, you need to add 1 to your range parameter (Max - Min) and then truncate the decimal part by casting to an int. This is accomplished via:

Min + (int)(Math.random() * ((Max - Min) + 1))

And there you have it. A random integer value in the range [Min,Max], or per the example [5,10]:

5 + (int)(Math.random() * ((10 - 5) + 1))
๐ŸŒ
Clojure Q&A
ask.clojure.org โ€บ index.php โ€บ 1893 โ€บ threadlocalrandom-instead-of-math-random
ThreadLocalRandom instead of Math/random - Clojure Q&A
May 11, 2014 - The clojure `rand-int` method seems to be 4 times slower than its java counterpart `java.util.Random.nextInt()`
๐ŸŒ
Baeldung
baeldung.com โ€บ home โ€บ java โ€บ java numbers โ€บ random number generators in java
Random Number Generators in Java | Baeldung
January 8, 2024 - In most cases, we donโ€™t have specific generator requirements. Thus, we can fetch the default generator directly from the RandomGenerator interface. This is the new recommended approach in Java 17, as an alternative to creating instances of Random:
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ java โ€บ random-vs-secure-random-numbers-java
Random vs Secure Random numbers in Java - GeeksforGeeks
July 23, 2025 - Generating Function: The standard Oracle JDK 7 implementation uses what's called a Linear Congruential Generator to produce random values in java.util.Random. Whereas Secure Random implements SHA1PRNG algorithm, which uses SHA1 to generate ...
๐ŸŒ
freeCodeCamp
freecodecamp.org โ€บ news โ€บ generate-random-numbers-java
Java Random Number Generator โ€“ How to Generate Integers With Math Random
November 25, 2020 - Similar to Math.random() , the nextDouble() returns a double type pseudo-random number, greater than or equal to zero and less than one. public static void main(String[] args) { // create Random object Random random = new Random(); // generates ...
๐ŸŒ
How to do in Java
howtodoinjava.com โ€บ home โ€บ generating random numbers in java
Generating Random Numbers in Java (with Thread Safety)
September 6, 2023 - Pseudo-Random Number Generator (PRNG) refers to an algorithm that uses mathematical formulas to produce sequences of random numbers. The java.util.Random class provides methods that can be used to generate a stream of pseudo-random numbers or ...
๐ŸŒ
iO Flood
ioflood.com โ€บ blog โ€บ java-random
Java Random: Generating Numbers with java.util.Random
March 5, 2024 - We also examined alternative approaches to random number generation, such as using the Math.random() function and leveraging third-party libraries. Along the way, we addressed common challenges that you might encounter when generating random numbers in Java, such as dealing with negative numbers ...
๐ŸŒ
Medium
medium.com โ€บ @AlexanderObregon โ€บ javas-math-random-method-explained-bafa91bf49a6
Javaโ€™s Math.random() Method Explained | Medium
November 30, 2024 - The randomness of Math.random() is sufficient for general programming needs like games or simple simulations. However, because it is deterministic, it should not be used for cryptographic purposes or applications requiring high levels of randomness. For such cases, Java offers alternatives like java.security.SecureRandom.
๐ŸŒ
Hacker News
news.ycombinator.com โ€บ item
There's Math.random(), and then there's Math.random() (2015) | Hacker News
November 9, 2023 - I have a little puzzle I've been trying to solve in my spare time; maybe someone here can point me in the right direction ยท The puzzle is: given a float from Math.random(), suppose you know only whether it is greater than it is then 0.5 (i.e you only see the result of a coin flip which depends ...
๐ŸŒ
Sentry
sentry.io โ€บ sentry answers โ€บ java โ€บ how do i generate random integers within a specific range in java?
How do I generate random integers within a specific range in Java? | Sentry
The best solution for your needs depends on the application you need random integers to be generated for. We can use the java.util.Random class to create a new random number generator, which we can then use to retrieve a pseudorandom, uniformly ...