Prashanth Babu

Ramblings on Hadoop Ecosytem, Java, etc.

Generating Random numbers in a Range in Java

Generating random numbers is usually a pain.
And more so when you have generate random numbers in a given range in Java. You have to consider a lot of parameters.

Java (< v8)

I would write something quick and dirty like the following.
For brevity, programming language syntax chosen is Scala, but you get the point.

val random = new java.util.Random
val (size, min, max) = (10, 20, 50)
for(i <- 0 until size) yield (min + random.nextDouble() * (max-min)).toInt

// Output of the above code in Scala REPL
res1: scala.collection.immutable.IndexedSeq[Int] = Vector(46, 38, 22, 21, 43, 35, 49, 47, 23, 41)

Python

Python has core library support for this feature. So, we can do the following:

from random import randint
[randint(10, 50) for p in range(10)]

## Output of the above code in Python REPL
[43, 33, 37, 20, 41, 11, 18, 25, 12, 26]

But wont it be cool if we had such an utility in the JDK itself as in Python to generate random numbers? So, this is where JDK v8 comes to help.

Java v8.x new methods

JDK v8 added the following nifty methods to java.util.Random class which help us in accomplishing this.

  1. Generate an unlimited number of random values »» public IntStream ints()
  2. Generate an unlimited number of random values within a range »» public IntStream ints (int randomNumberOrigin, int randomNumberBound)
  3. Generate ‘n’ random integers »» public IntStream ints(long streamSize)
  4. Generate ‘n’ random integers in a given range »» public IntStream ints(long streamSize, int randomNumberOrigin, int randomNumberBound)

Also, similar utility methods are present for long and double datatypes respectively.

Please take a note that each of these methods are actually returning an java.util.stream.IntStream and not an Array.
And another point to note here is: [randomNumberOrigin, randomNumberBound) i.e. random numbers generated will be randomNumberOrigin ≤ x < randomNumberBound.

Code with Java v8

So, with this background we can modify our initial code to utilize the new(ish) Java API directly:

val random = new java.util.Random
val (size, min, max) = (10, 20, 50)
random.ints(size, min, max).toArray  

// Output of the above code in Scala REPL
res2: Array[Int] = Array(21, 43, 48, 33, 32, 48, 27, 25, 46, 32)

And similarly we can check the other methods as well.

random.longs(size, min, max).toArray
res3: Array[Long] = Array(32, 44, 24, 34, 40, 29, 45, 24, 43, 30)

random.doubles(3, min, max).toArray
res4: Array[Double] = Array(38.10858166740068, 22.464983440394192, 43.64737980712431)

Fairly simple and no need to reinvent the wheel.
Happy learning!