【问题标题】:why does Random(System.currentTimeMillis()); give me repeated values (Java)? [duplicate]为什么 Random(System.currentTimeMillis());给我重复的值(Java)? [复制]
【发布时间】:2019-03-04 20:18:25
【问题描述】:

我是一名 Java 程序员新手,需要创建两个随机数。我们被指示使用 System.currentTimeMillis() 但是我不知道为什么我会得到这么多重复的数字。

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;     

    }


}

输出: 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

【问题讨论】:

  • 我们被指示使用 System.currentTimeMillis()... 你是如何被指示使用它的?也许你不应该这样使用它。
  • 除非您需要可重复的结果,否则您不应该明确地播种 Random。你应该重用同一个实例。
  • 播种一次并重复使用您的 Random 实例。

标签: java


【解决方案1】:

Random() 构造函数的参数是随机数生成器的种子。每次您使用相同的种子创建一个新的Random 实例时,它都会生成相同的数字。由于diceGen() 的执行时间不到一毫秒,因此您正在创建具有相同毫秒计数的多个实例。

相反,您需要创建一个 Random 实例并将其存储在字段中或将其作为参数传递。

【讨论】:

    【解决方案2】:

    代码执行得足够快,以至于在循环的两次迭代之间,System.currentTimeMillis() 返回的值保持不变。因此,这些Random 实例使用相同的种子创建并返回相同的值。

    考虑使用 System.nanoTime() 或构建单个 Random 实例并在所有迭代中重用它。

    类似

    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;
    }
    

    【讨论】:

    • 是的,解决方法是不要使用相同的种子创建 rng - 制作单例 rng - 因为每个后续调用都会返回一个新数字。
    • @Micromuncher 当然,已编辑。
    【解决方案3】:

    使 rng 在范围内具有全局性。每次通话都会改变号码。如果您每次调用生成器时都为 rng 播种,那么您很可能会在同一个刻度上调用种子,因此得到相同的数字。

    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;     
    
    }
    
    
    }
    

    rngs 的工作方式是x = trunc( old_x * big_prime ) + prime,第一次调用 old_x 是种子。

    【讨论】:

    • 请考虑为您的解决方案提供解释,以帮助 OP 理解问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    • 1970-01-01
    • 1970-01-01
    • 2012-08-31
    • 2023-03-29
    • 2020-02-05
    • 1970-01-01
    相关资源
    最近更新 更多