Random
Java programs sometimes need a source of random numbers. Consider generating a user ID—a random source of digits could help.
Class
notesIn Java we use the Random
class
(from java.util.Random
) and Math.random
. These types return pseudo-random numbers, which are good enough for most programs.
Math.random
Consider this program. It calls the Math.random
method and assigns a double
variable to the result. That double
is anywhere between 0 and 1.
Math.random
is sufficient. But using Random
directly is better for more complex features.import java.lang.Math; public class Program { public static void main(String[] args) { // Random number between 0 and 1. double value = Math.random(); System.out.println(value); } }0.24645081324805196
Random
ObjectHere we instantiate directly the Random
class
. With a Random
instance, we call methods (like nextInt
) to get the "next" random number.
Random
object internally stores a state, based (by default) on a time seed. The stream returns the "next" number.nextInt
, the max integer returned is less than that value (not equal to it). It is greater than 0.import java.util.Random; public class Program { public static void main(String[] args) { // Create new Random and call nextInt on it twice. Random random = new Random(); int random1 = random.nextInt(); int random2 = random.nextInt(10); // Display results. System.out.println(random1); System.out.println(random2); } }-1838898462 6
Random
This is a common design pattern for the Random
class
. We create it as a field (often a static
field) in the enclosing class
. Then we use that field to generate numbers.
static
Random
field, we reduce object creation, and avoid any time-based seed issues from code that executes near in time.Random
uses a seed based on the time. So if we call it many times near in time, it may lead to poor results. A field helps.import java.util.Random; public class Program { static Random _random = new Random(); static void test() { // Use static Random instance. // ... This reduces object creation. int number = _random.nextInt(5); System.out.println(number); } public static void main(String[] args) { // Call test method three times. test(); test(); test(); } }3 0 2
Random
byte
arrayWith the nextBytes()
method on the Random
class
, we can fill an entire byte
array with random byte
values. The size is not important—the entire array is filled.
import java.util.Random; public class Program { public static void main(String[] args) { Random random = new Random(); byte[] array = new byte[10]; // ... Generate random bytes 5 times. for (int i = 0; i < 5; i++) { // Fill existing array with random bytes. random.nextBytes(array); // Display. for (int x = 0; x < array.length; x++) { System.out.print(array[x]); System.out.print(" "); } System.out.println(); } } }-95 49 92 -106 117 67 -97 116 109 100 -8 -50 -18 63 82 -10 122 6 -51 74 -25 -36 54 37 -115 -8 -61 21 43 63 -44 105 107 -109 -100 -4 41 -19 127 -91 -116 12 49 100 -110 -58 -83 -84 44 26
We can get a stream of random ints from the Random
class
. We call ints()
on Random
. And we can use the stream like any other—here we use iterator()
can call nextInt
5 times.
IntStream
is a specialized stream. For stream-based designs, the Random.ints()
method can help simplify code.import java.util.PrimitiveIterator; import java.util.Random; import java.util.stream.IntStream; public class Program { public static void main(String[] args) { // Use ints to get a random stream of ints. Random r = new Random(); IntStream stream = r.ints(); PrimitiveIterator.OfInt iterator = stream.iterator(); // Call nextInt on the iterator to get random numbers. for (int i = 0; i < 5; i++) { int n = iterator.nextInt(); System.out.println(n); } } }-1775913741 1599836970 515709788 1578549166 7961094
Random
textWe can use Random
to generate random phrases (like a spam email). We use nextInt
to generate random indexes into an array or ArrayList
.
StringBuilder
. We use the array's length as the exclusive upper bound.import java.util.Random; import java.lang.StringBuilder; public class Program { public static void main(String[] args) { // Create String array of words. String[] words = { "hello,", "cat,", "food", "buy", "free", "click", "here" }; Random random = new Random(); StringBuilder builder = new StringBuilder(); // Append five random words to the StringBuilder. for (int i = 0; i < 5; i++) { // Get random index (use length as nextInt is exclusive). int index = (int) random.nextInt(words.length); builder.append(words[index]); builder.append(" "); } // Remove final space and trailing punctuation. builder.setLength(builder.length() - 1); if (builder.charAt(builder.length() - 1) == ',') { builder.setLength(builder.length() - 1); } builder.append("!"); // Uppercase the StringBuilder. builder.setCharAt(0, Character.toUpperCase(builder.charAt(0))); // Print result. System.out.println(builder); } }Cat, free hello, food cat!
With the Fisher-Yates shuffling algorithm, we make just one pass through an array, and rearrange all elements. This is fast. But the code seems prone to errors.
Random
lowercase letterWith nextInt
we can get random integers in a range. And we can convert those ints into chars to get a stream of random lowercase letters.
With nextInt()
we can specify a range of numbers. But a modulo division can help us test random numbers in additional ways.
For the fastest program, it is usually best to avoid generating more random numbers than needed. A random sequence can be cached (as in an array) in memory.
With the Random
class
, we get a stream of pseudo-random numbers. For scientific work, or money-related programs, a better random stream can employed. But often Random
is enough.