How do I generate random integers within a specific range in Java?

How do I generate a random int value in a specific range?

I have tried the following, but those do not work:

Attempt 1:

randomNum = minimum + (int)(Math.random() * maximum);
// Bug: `randomNum` can be bigger than `maximum`.

Attempt 2:

Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum =  minimum + i;
// Bug: `randomNum` can be smaller than `minimum`.

Answers


private static Random random = new Random();    

public static int getRandomInt(int min, int max){
  return random.nextInt(max - min + 1) + min;
}

OR

public static int getRandomInt(Random random, int min, int max)
{
  return random.nextInt(max - min + 1) + min;
}

I use this:

 /**
   * @param min - The minimum.
   * @param max - The maximum.
   * @return A random double between these numbers (inclusive the minimum and maximum).
   */
 public static double getRandom(double min, double max) {
   return (Math.random() * (max+1-min)) + min;
 }

You can cast it to an Integer if you want.


import java.util.Random; 

public class RandomUtil {
    // Declare as class variable so that it is not re-seeded every call
    private static Random random = new Random();

    /**
     * Returns a psuedo-random number between min and max (both inclusive)
     * @param min Minimim value
     * @param max Maximim value. Must be greater than min.
     * @return Integer between min and max (both inclusive)
     * @see java.util.Random#nextInt(int)
     */
    public static int nextInt(int min, int max) {
        // nextInt is normally exclusive of the top value,
        // so add 1 to make it inclusive
        return random.nextInt((max - min) + 1) + min;
    }
}

You can use this code snippet which will resolve your problem:

Random r = new Random();
int myRandomNumber = 0;
myRandomNumber = r.nextInt(maxValue-minValue+1)+minValue;

Use myRandomNumber (which will give you a number within a range).


You can do something like this:

import java.awt.*;
import java.io.*;
import java.util.*;
import java.math.*;

public class Test {

    public static void main(String[] args) {
        int first, second;

        Scanner myScanner = new Scanner(System.in);

        System.out.println("Enter first integer: ");
        int numOne;
        numOne = myScanner.nextInt();
        System.out.println("You have keyed in " + numOne);

        System.out.println("Enter second integer: ");
        int numTwo;
        numTwo = myScanner.nextInt();
        System.out.println("You have keyed in " + numTwo);

        Random generator = new Random();
        int num = (int)(Math.random()*numTwo);
        System.out.println("Random number: " + ((num>numOne)?num:numOne+num));
    }
}

I will simply state what is wrong with the solutions provided by the question and why the errors.

Solution 1:

randomNum = minimum + (int)(Math.random()*maximum); 

Problem: randomNum is assigned values numbers bigger than maximum.

Explanation: Suppose our minimum is 5, and your maximum is 10. Any value from Math.random() greater than 0.6 will make the expression evaluate to 6 or greater, and adding 5 makes it greater than 10 (your maximum). The problem is you are multiplying the random number by the maximum (which generates a number almost as big as the maximum) and then adding the minimum. Unless the minimum is 1, it's not correct. You have to switch to, as mentioned in other answers

randomNum = minimum + (int)(Math.random()*(maximum-minimum+1))

The +1 is because Math.random() will never return 1.0.

Solution 2:

Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum =  minimum + i;

Your problem here is that '%' may return a negative number if the first term is smaller than 0. Since rn.nextInt() returns negative values with ~50% chance, you will also not get the expected result.

This, was, however, almost perfect. You just had to look a bit further down the Javadoc, nextInt(int n). With that method available, doing

Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt(n);
randomNum =  minimum + i;

Would also return the desired result.


A different approach using Java 8 IntStream and Collections.shuffle

import java.util.stream.IntStream;
import java.util.ArrayList;
import java.util.Collections;

public class Main {

    public static void main(String[] args) {

        IntStream range = IntStream.rangeClosed(5,10);
        ArrayList<Integer> ls =  new ArrayList<Integer>();

        //populate the ArrayList
        range.forEach(i -> ls.add(new Integer(i)) );

        //perform a random shuffle  using the Collections Fisher-Yates shuffle
        Collections.shuffle(ls);
        System.out.println(ls);
    }
}

The equivalent in Scala

import scala.util.Random

object RandomRange extends App{
  val x =  Random.shuffle(5 to 10)
    println(x)
}

You could use

RandomStringUtils.randomNumeric(int count)

method also which is from apache commons.


Random random = new Random();
int max = 10;
int min = 3;
int randomNum = random.nextInt(max) % (max - min + 1) + min;

I am thinking to linearly normalize the generated random numbers into desired range by using the following. Let x be a random number, let a and b be the minimum and maximum range of desired normalized number.

Then below is just a very simple code snipplet to test the range produced by the linear mapping.

public static void main(String[] args) {
    int a = 100;
    int b = 1000;
    int lowest = b;
    int highest = a;
    int count = 100000;
    Random random = new Random();
    for (int i = 0; i < count; i++) {
        int nextNumber = (int) ((Math.abs(random.nextDouble()) * (b - a))) + a;
        if (nextNumber < a || nextNumber > b) {
            System.err.println("number not in range :" + nextNumber);
        }
        else {
            System.out.println(nextNumber);
        }
        if (nextNumber < lowest) {
            lowest = nextNumber;
        }
        if (nextNumber > highest) {
            highest = nextNumber;
        }
    }
    System.out.println("Produced " + count + " numbers from " + lowest
            + " to " + highest);
}

I just generate a random number using Math.random() and multiply it by a big number, let's say 10000. So, I get a number between 0 to 10,000 and call this number i. Now, if I need numbers between (x, y), then do the following:

i = x + (i % (y - x));

So, all i's are numbers between x and y.

To remove the bias as pointed out in the comments, rather than multiplying it by 10000 (or the big number), multiply it by (y-x).


import java.util.Random;

public class RandomSSNTest {

    public static void main(String args[]) {
        generateDummySSNNumber();
    }


    //831-33-6049
    public static void generateDummySSNNumber() {
        Random random = new Random();

        int id1 = random.nextInt(1000);//3
        int id2 = random.nextInt(100);//2
        int id3 = random.nextInt(10000);//4

        System.out.print((id1+"-"+id2+"-"+id3));
    }

}

You can also use

import java.util.concurrent.ThreadLocalRandom;
Random random = ThreadLocalRandom.current();

However, this class doesn’t perform well in a multi-threaded environment.


Making the following change in Attempt 1 should do the work -

randomNum = minimum + (int)(Math.random() * (maximum - minimum) );

Check this for working code.


One of my friends had asked me this same question in university today (his requirements was to generate a random number between 1 & -1). So I wrote this, and it works fine so far with my testing. There are ideally a lot of ways to generate random numbers given a range. Try this:

Function:

private static float getRandomNumberBetween(float numberOne, float numberTwo) throws Exception{

    if (numberOne == numberTwo){
        throw new Exception("Both the numbers can not be equal");
    }

    float rand = (float) Math.random();
    float highRange = Math.max(numberOne, numberTwo);
    float lowRange = Math.min(numberOne, numberTwo);

    float lowRand = (float) Math.floor(rand-1);
    float highRand = (float) Math.ceil(rand+1);

    float genRand = (highRange-lowRange)*((rand-lowRand)/(highRand-lowRand))+lowRange;

    return genRand;
}

Execute like this:

System.out.println( getRandomNumberBetween(1,-1));

I think this code will work for it. Please try this:

import java.util.Random;
public final class RandomNumber {

    public static final void main(String... aArgs) {
        log("Generating 10 random integers in range 1..10.");
        int START = 1;
        int END = 10;
        Random randomGenerator = new Random();
        for (int idx=1; idx<=10; ++idx) {

            // int randomInt=randomGenerator.nextInt(100);
            // log("Generated : " + randomInt);
            showRandomInteger(START,END,randomGenerator);
        }
        log("Done");
    }

    private static void log(String aMessage) {
        System.out.println(aMessage);
    }

    private static void showRandomInteger(int aStart, int aEnd, Random aRandom) {
        if (aStart > aEnd) {
            throw new IllegalArgumentException("Start cannot exceed End.");
        }
        long range = (long)aEnd - (long)aStart + 1;
        long fraction = (long) (range * aRandom.nextDouble());
        int randomNumber = (int) (fraction + aStart);
        log("Generated" + randomNumber);
    }
}

You can either use the Random class to generate a random number and then use the .nextInt(maxNumber) to generate a random number. The maxNumber is the number that you want the maximum when generating a random number. Please remember though, that the Random class gives you the numbers 0 through maxNumber-1.

Random r = new Random();
int i = r.nextInt();

Another way to do this is to use the Math.Random() class which many classes in schools require you to use because it is more efficient and you don't have to declare a new Random object. To get a random number using Math.Random() you type in:

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

This will generate Random numbers list with range (Min - Max) with no duplicate.

generateRandomListNoDuplicate(1000, 8000, 500);

Add this method.

private void generateRandomListNoDuplicate(int min, int max, int totalNoRequired) {
    Random rng = new Random();
    Set<Integer> generatedList = new LinkedHashSet<>();
    while (generatedList.size() < totalNoRequired) {
        Integer radnomInt = rng.nextInt(max - min + 1) + min;
        generatedList.add(radnomInt);
    }
}

Hope this will help you.


I have created a method to get a unique integer in a given range.

/*
      * minNum is the minimum possible random number
      * maxNum is the maximum possible random number
      * numbersNeeded is the quantity of random number required
      * the give method provides you with unique random number between min & max range
*/
public static Set<Integer> getUniqueRandomNumbers( int minNum , int maxNum ,int numbersNeeded ){

    if(minNum >= maxNum)
        throw new IllegalArgumentException("maxNum must be greater than minNum");

    if(! (numbersNeeded > (maxNum - minNum + 1) ))
        throw new IllegalArgumentException("numberNeeded must be greater then difference b/w (max- min +1)");

    Random rng = new Random(); // Ideally just create one instance globally

    // Note: use LinkedHashSet to maintain insertion order
    Set<Integer> generated = new LinkedHashSet<Integer>();
    while (generated.size() < numbersNeeded)
    {
        Integer next = rng.nextInt((maxNum - minNum) + 1) + minNum;

        // As we're adding to a set, this will automatically do a containment check
        generated.add(next);
    }
    return generated;
}

If you already use Commons Lang API 2.x or latest version then there is one class for random number generation RandomUtils.

public static int nextInt(int n)

Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), from the Math.random() sequence.

Parameters: n - the specified exclusive max-value

int random = RandomUtils.nextInt(1000000);

Note: In RandomUtils have many methods for random number generation


The following is another example using Random and forEach

int firstNum = 20;//Inclusive
int lastNum = 50;//Exclusive
int streamSize = 10;
Random num = new Random().ints(10, 20, 50).forEach(System.out::println);

Say you want range between 0-9, 0 is minimum and 9 is maximum. The below function will print anything between 0 and 9. It's the same for all ranges.

public static void main(String[] args) {
    int b = randomNumberRange(0, 9);
    int d = randomNumberRange (100, 200);
    System.out.println("value of b is " + b);
    System.out.println("value of d is " + d);
}

public static int randomNumberRange(int min, int max) {
    int n = (max + 1 - min) + min;
    return (int) (Math.random() * n);
}

The below code generates a random number between 100,000 and 900,000. This code will generate six digit values. I'm using this code to generate a six-digit OTP.

Use import java.util.Random to use this random method.

import java.util.Random;

// Six digits random number generation for OTP
Random rnd = new Random();
long longregisterOTP = 100000 + rnd.nextInt(900000);
System.out.println(longregisterOTP);

This is the easy way to do this.

import java.util.Random;
class Example{
    public static void main(String args[]){
        /*-To test-
        for(int i = 1 ;i<20 ; i++){
            System.out.print(randomnumber()+",");
        }
        */

        int randomnumber = randomnumber();

    }

    public static int randomnumber(){
        Random rand = new Random();
        int randomNum = rand.nextInt(6) + 5;

        return randomNum;
    }
}

In there 5 is the starting point of random numbers. 6 is the range including number 5.


Try using org.apache.commons.lang.RandomStringUtils class. Yes, it sometimes give a repeated number adjacently, but it will give the value between 5 and 15:

    while (true)
    {
        int abc = Integer.valueOf(RandomStringUtils.randomNumeric(1));
        int cd = Integer.valueOf(RandomStringUtils.randomNumeric(2));
        if ((cd-abc) >= 5 && (cd-abc) <= 15)
        {
            System.out.println(cd-abc);
            break;
        }
    }

Random number from the range [min..max] inclusive:

int randomFromMinToMaxInclusive = ThreadLocalRandom.current()
        .nextInt(min, max + 1);

Most of above suggestion don't consider 'overflow', For example: min = Integer.MIN_VALUE, max = 100. One of correct approaches I have so far is:

final long mod = max- min + 1L;
final int next = (int) (Math.abs(rand.nextLong() % mod) + min);

There is a library at https://sourceforge.net/projects/stochunit/ for handling selection of ranges.

StochIntegerSelector randomIntegerSelector = new StochIntegerSelector();
randomIntegerSelector.setMin(-1);
randomIntegerSelector.setMax(1);
Integer selectInteger = randomIntegerSelector.selectInteger();

It has edge inclusion/preclusion.


Use java.util for Random for general use.

You can define your minimum and maximum range to get those results.

Random rand=new Random();
rand.nextInt((max+1) - min) + min;

public static void main(String[] args) {

    Random ran = new Random();

    int min, max;
    Scanner sc = new Scanner(System.in);
    System.out.println("Enter min range:");
    min = sc.nextInt();
    System.out.println("Enter max range:");
    max = sc.nextInt();
    int num = ran.nextInt(min);
    int num1 = ran.nextInt(max);
    System.out.println("Random Number between given range is " + num1);

}

A simple way to generate n random numbers between a and b e.g a =90, b=100, n =20

Random r = new Random();
for(int i =0; i<20; i++){
    System.out.println(r.ints(90, 100).iterator().nextInt());
}

r.ints() returns an IntStream and has several useful methods, have look at its API.


Need Your Help

Questions about implementation of a global register allocator for the tiny c compiler

compiler-construction time compiler-theory tcc

upcoming summer i will hopefully start writing my masters thesis and i have been quite busy looking for a thesis subject. I now have a pool of subjects that i am interested in and the one that stru...

Can I see the log of which files were opened on my system for the past one hour in windows 7?

windows windows-7

Someone has logged in as admin into my system and i want to see which files did he open?