2

I have the following class:

public class CardGenerator {
    private static final Random random = new Random();

    private CardGenerator() {

    }

    public static long generateNumber() {
        int identifier = random.nextInt(1_000_000_000 - 100_000_000 + 1)
                                      + 100_000_000; //9 digits
        long number = 400_000 * 1_000_000_000L
                    + identifier; //15 digits
        int checksum = Luhn.getChecksum(number);
        number = number * 10 + checksum; //16 digits
        return number;
    }

    public static int generatePIN() {
        return random.nextInt(10_000 - 1_000 + 1) + 1_000; //4 digits
    }
}

or is it better practice to create a new Random object in every method?

Joyce
  • 59
  • 7
  • Does this answer your question? [How do I generate random integers within a specific range in Java?](https://stackoverflow.com/questions/363681/how-do-i-generate-random-integers-within-a-specific-range-in-java) – Glains Oct 27 '20 at 14:03
  • 2
    Neither. I'd say it's better not to create `java.util.Random` at all. For high performance RNG, use [`ThreadLocalRandom`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/ThreadLocalRandom.html). For cryptographically strong RNG, use [`SecureRandom`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/security/SecureRandom.html). – apangin Oct 27 '20 at 15:37

2 Answers2

1

"Better" always depends on your exact requirements.

The things to consider:

  • do you want your code to be testable (the above is only to a certain degree)
  • do you want your code to work in a multi threaded environment, and should the different threads see the same random numbers

In other words, the distinct non-answer: you have to understand the contract that your code will be used for. Then you can decide what is appropriate.

The above is probably okay on a "throw away after single exercise" level, but not more.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
0

You might be thinking, that generating a new Random object might create numbers more, eh, randomly. But this is not the case. Calling next() always changes the seed used to create random numbers.

protected int next(int bits) { // is called by nextInt()
    long oldseed, nextseed;
    AtomicLong seed = this.seed;
    do {
        oldseed = seed.get();
        nextseed = (oldseed * multiplier + addend) & mask;
    } while (!seed.compareAndSet(oldseed, nextseed));
    return (int)(nextseed >>> (48 - bits));
}

So you have no advantages in creating a new Random object each time but you have a bit less performance because you are always creating a new object.

So yes, it's totally okay to stick with one Random object.

Milgo
  • 2,617
  • 4
  • 22
  • 37