2

I'm a novice Java programmer and need to create two random numbers. We were instructed to use System.currentTimeMillis() however I don't know why I am getting so many repeated numbers.

import java.util.Random;

public class TestClass1 {

    public static void main(String[] args) { 
        int points = 0;
        while (points < 100) {
        int[] scoreInfo = diceGen();
        System.out.println(scoreInfo[0]);
        System.out.println(scoreInfo[1]);
        points += 1;
        }
    }

    public static int[] diceGen() {
        Random num = new Random(System.currentTimeMillis());
        int dice1 = num.nextInt(6)+1;
        int dice2 = num.nextInt(6)+1;
        int[] numbers = {dice1, dice2};
        return numbers;     

    }


}

Output: 6 6 6 6 6 6 6 6 6 6 6 6 6 6 4 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 3 4 3 4 3 4 3 4 3 4 3 4 3 4 3 4 3 4 3 4 3 4 3 4 3 4 3 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5

  • _We were instructed to use System.currentTimeMillis()_... How were you instructed to use it? Maybe you were not supposed to use it like this. – lealceldeiro Sep 28 '18 at 20:08
  • 2
    You shouldn't be seeding `Random` explicitly unless you need reproducible results. And you should be reusing the same instance. – shmosel Sep 28 '18 at 20:15
  • 1
    Seed it once and reuse your `Random` instance. – khelwood Sep 28 '18 at 20:18

3 Answers3

5

The parameter to the Random() constructor is the seed to the random number generator. Every time you create a new Random instance with the same seed, it will generate the same numbers. Since an execution of diceGen() takes less than a millisecond, you're creating multiple instances with the same millisecond count.

Instead, you need to create a single Random instance and store it in a field or pass it as a parameter.

yole
  • 92,896
  • 20
  • 260
  • 197
2

The code is executing fast enough that between two iterations of the loop, the value returned by System.currentTimeMillis() remains the same. Those Random instances are therefore created with the same seed and return the same values.

Consider using System.nanoTime() or construct a single Random instance and reuse it in all of your iterations.

Something like

public static void main(String[] args) {
    int points = 0;
    Random num = new Random(System.nanoTime());
    while (points < 100) {
        int[] scoreInfo = diceGen(num);
        System.out.println(scoreInfo[0] + ", " + scoreInfo[1]);
        points += 1;
    }
}

public static int[] diceGen(Random num) {
    int dice1 = num.nextInt(6) + 1;
    int dice2 = num.nextInt(6) + 1;
    int[] numbers = { dice1, dice2 };
    return numbers;
}
Savior
  • 3,225
  • 4
  • 24
  • 48
-1

Make the rng global in scope. Each call will change the number. If you seed the rng each time you call the generator, chances are you will call the seed on the same tick and so get the same number.

import java.util.Random;

public class TestClass1 {
static public Random num = new Random(System.currentTimeMillis());

public static void main(String[] args) { 
    int points = 0;
    while (points < 100) {
    int[] scoreInfo = diceGen();
    System.out.println(scoreInfo[0]);
    System.out.println(scoreInfo[1]);
    points += 1;
    }
}

public static int[] diceGen() {        
    int dice1 = num.nextInt(6)+1;
    int dice2 = num.nextInt(6)+1;
    int[] numbers = {dice1, dice2};
    return numbers;     

}


}

The way rngs work is x = trunc( old_x * big_prime ) + prime and on first call old_x is the seed.

Micromuncher
  • 903
  • 7
  • 19
  • 3
    Please consider giving explanation for your solution to help the OP understand the problem – LxL Sep 28 '18 at 20:14