Java tutorials home  java.util.Random  Random number generators  XORShift  High quality random  Seeding generators  Entropy  SecureRandom  Random sampling  Random simulations and nextGaussian()

Using java.util.Random

In our introduction to random numbers in Java, we saw a brief example of generating random integers with the java.util.Random class. On this page, we'll look in a little more detail at how this class works. This will give us some guidance on how to use it most effectively, and when not to use it.

Tips for using java.lang.Random

First, some practical advice. If you don't want to get too theoretical, and you just want a casual random number generator, e.g. for a dice roll or the starting position of a baddy in your next blockbuster game, then java.lang.Random is still OK for that kind of use if you at least make the most of the class:

  • Use the most appropriate method provided by the Random class. The library implementers understand the limitations of the method used by java.lang.Random, and have at least provided methods to get round them as much as possible. For example, if you need a random bit, always use nextBoolean(); don't invent an ad-hoc solution, such as taking nextInt() and ANDing with 1. For subtle reasons, this will produce less random results.

  • Similarly, don't use the following "idiom":

    // This is WRONG -- don't do this!!
    int no = Math.abs(r.nextInt()) % n;

    If you do this, then depending on n, you will either bias your results or not make them as random as they could be. If you need an integer between 0 and some upper bound, use the corresponding method provided by the Random class rather than inventing some other, incorrect solution.

  • Avoid using the class for tests based on a power of two— especially a low power of two— such as the following1:

    if (r.nextInt() >= 4) {

    and especially especially where you mask off some number of low bits and then test:

    if ((r.nextInt() & 0x7fff) >= 4) {

    It's easy for this kind of situation to crop up accidentally when using java.lang.Random to generate test data, and can mean your "test" executes different or biased code paths compared to "real" situations. To understand why this kind of use of Random isn't very good, see the section on the randomness of bit positions.

  • Never use java.lang.Random for "serious" use, such as scientific experiments, generating session IDs on a web server, or gambling programs where money is involved.

  • If possible, avoid using java.lang.Random for choosing "groups of numbers" (e.g. 3D coordinates) or "groups of random items" (e.g. random strings of a certain length): the method used has serious limitations on the range and randomness of combinations it can generate.

Next: how does java.lang.Random work, and how good is it?

If you want to understand the above issues in more detail, then the next section deals with the "Java Random algorithm", looking at how java.lang.Random works and some of its limitations.

You should also look at the section on alternatives to java.util.Random, which looks at various random number generators that you could use as a higher-quality replacement. In particular, you should look at:

  • the XORShift generator, which provides a low-cost random number generation technique that avoids many of the problems of java.util.Random;
  • the SecureRandom class, for cases where you need a cryptography-quality random number generator (in general, where security depends on the quality and unpredictability of the random numbers you generate);
  • the Numerical Recipes algorithm, which often provides a good compromise between speed and quality of generation.

1. Just to be clear: the simple test of >= effectively first tests if the number is positive or negative. That part will be reasonably random). Then in the case of the number being positive, the expression tests if bit 2 is set. This latter stage will introduce a high element of non-randomness.

comments powered by Disqus

Written by Neil Coffey. Copyright © Javamex UK 2013. All rights reserved.