Java Random.nextInt()仅在循环中重复数字

时间:2019-03-22 12:38:47

标签: java

我正在尝试以程序方式在2D网格上生成一个世界。对于随机数生成,我正在使用单个 全局java.utils.Random 实例和一个种子。
像这样:

public class Game {

    private static final int SEED = 1111;
    private static final Random RANDOM = new Random(SEED);
    private static final int roomsCount = generateRandomNumberOfRooms();
}

一切正常,直到我编写了此方法:

public ArrayList<XYCoords> generateRandomCoordinates(){
        ArrayList<XYCoords> coords = new ArrayList<>(roomsCount);

        for(int i = 0; i < roomsCount; i+=1) {
            XYCoords xy = new XYCoords(RANDOM.nextInt(WIDTH),  RANDOM.nextInt(HEIGHT));
            coords.add(xy);
        }
        return coords;
    }

当我执行它时,会得到 XYCoordinates 的列表,但是它们都有相同的两个 X Y 值,例如(11 ,20)或(12,5)...等所有房间都降落在同一地点。在我看来,for循环中对 RANDOM.nextInt()的调用不会更新实例RANDOM的状态。
在我称为RANDOM.nextInt()的所有其他函数中,它都能正常工作。其中一些也用于循环。问题仅在于此功能。它直接在main()中使用一次,而不嵌套在任何地方。
有谁知道问题可能在哪里?如果需要,我可以上传更多代码,但是我认为这无关紧要。

1 个答案:

答案 0 :(得分:2)

不必要的行为1 :每次运行的应用程序都以相同的顺序生成相同的值。原因是您的RANDOM对象用种子实例化。尝试以下调整:(删除种子,允许Random为您提供随机值):

public class Game {

    private static final Random RANDOM = new Random();
    private static final int roomsCount = generateRandomNumberOfRooms();
}

如果由于某种原因需要种子,则可以尝试在每次启动时更新种子。

澄清种子的实际作用:

(请注意,如果您提供了种子,也可以从构造函数中设置种子)

  

setSeed

     

公共无效setSeed(长种子)

     

设置此随机种子   使用单个长种子的数字生成器。总合同   setSeed是它更改此随机数生成器的状态   对象,使其处于与之前完全相同的状态   用参数seed作为种子创建。 setSeed方法是   由class Random实现,方法是将种子自动更新为(seed ^   0x5DEECE66DL)&((1L << 48)-1)并清除haveNextNextGaussian   nextGaussian()使用的标志。 setSeed的实现按类   随机碰巧只使用给定种子的48位。一般来说,   但是,覆盖方法可以使用long参数的所有64位   作为种子值。

     

参数:seed-初始种子

不需要的行为2 :循环后的线完全一样。 XYCoords类可能将xy声明为static变量。 解决方案:删除静态声明。由于值是静态的,因此对象在绑定到类时共享这些值。设置的最后一个值是在所有XYCoords对象上进行迭代时将获得的值。

通常,这是两种情况的混合,导致结果始终是相同的值。