Java: Can (new Random ()). Does NextInt (5) always return the same number?

Sometimes this piece of code always returns the same number (and sometimes it works fine):

(new Random()).nextInt(5) 

I have a suspicion where the problem is - it probably always creates a new Random with the same seed. So what would be the best solution:

  • create a static var for Random () and use it instead.
  • use Math.random () * 5 (it looks like it uses static var inside)

or something else? I don't need anything fancy, just something that looks random.

It would also be helpful if someone could explain why the source code sometimes works and sometimes not.

Thanks.

+4
source share
6 answers

javadoc for java.util.Random is clear:

If two instances of Random are created with the same seed, and with the same sequence of method calls performed for each, they will generate and return identical sequences of numbers.

The default constructor is also clear:

Creates a new random number generator. This constructor sets the seed of a random number generator to a value likely to be different from any other call to this constructor.

In other words, no guarantees.

If you need a more random algorithm, use java.security.SecureRandom.

+12
source

If you call this line of code on consecutive lines, then yes, two random instances that you create can be created with the same seed from the clock (counting the number of seconds milliseconds is the default value for Random objects). Almost universally, if an application requires multiple random numbers, you should create one instance of Random and reuse it as often as you need.

Edit: It is interesting to note that javadoc for Random has changed from 1.4.2, which explains that the clock is used as the default seed. Apparently, this is no longer a guarantee.

Edit # 2: By the way, even with a properly selected instance of Random that you are reusing, you will still get the same random number as the previous call, about 1/5 times when you call nextInt(5) .

 public static void main(String[] args) { Random rand = new Random(); int count = 0; int trials = 10000; int current; int previous = rand.nextInt(5); for(int i=0; i < trials; ++i) { current = rand.nextInt(5); if( current == previous ) { count++; } } System.out.println("Random int was the same as previous " + count + " times out of " + trials + " tries."); } 
+6
source

... Sometimes this piece of code [..] returns the same number (and sometimes it works fine) ...

So does this work by accident? :) :) :)

Alright, alright, take me off now!

+4
source

In Java 1.4, the default semantics for a new instance of Random were specified in the API documentation for the result of System.currentTimeMillis() . Obviously, a narrow loop can create many instances of Random() for each tick, all of which have the same seed and all produce the same pseudo-random sequence. This was especially bad on some platforms, such as Windows, where the clock resolution was low (10 ms or more).

Since Java 5, however, the seed is set "to a value that may be different" for each default constructor call. When using a different seed for each instance of Random results should appear random as desired.

+3
source

Javadoc for Random is not explicit about this, but the seed it uses probably depends on the current system time. He claims that random numbers will be the same for the same seed. If you use the call within the same millisecond, it will use the same seed. The best solution is probably to use a static Random object and use it for subsequent method calls.

+1
source

The best way to approximate the uniform distribution is to use the static method Random.nextInt (n) to create integers in the range [0, n-1] (Yes, n is excluded). In your specific example, if you need integers ranging from 0 to 5 inclusive, you should call Random.nextInt (6).

+1
source

Source: https://habr.com/ru/post/1286762/


All Articles