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

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

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

最佳答案

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

public class Game {

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

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

澄清种子的实际作用:

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

setSeed

public void setSeed(long seed)

Sets the seed of this random number generator using a single long seed. The general contract of setSeed is that it alters the state of this random number generator object so as to be in exactly the same state as if it had just been created with the argument seed as a seed. The method setSeed is implemented by class Random by atomically updating the seed to (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1) and clearing the haveNextNextGaussian flag used by nextGaussian(). The implementation of setSeed by class Random happens to use only 48 bits of the given seed. In general, however, an overriding method may use all 64 bits of the long argument as a seed value.

Parameters: seed - the initial seed

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

一般来说,这是两者的混合,导致您始终获得相同的值。

关于Java Random.nextInt() 仅在循环中重复数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55299791/

相关文章:

java - 南面板和北面板使用哪个布局管理器?

java - 当我在 AndroidManifest.xml 中指定 minSdkVersion 时,标题栏会缩小

java - 如何给所有HttpClient请求方法添加参数?

Java eclipse 突出显示缺少的括号

java - 如何在 Java 中生成 map ?

java - 如何阻止 JFace 组合框在窗口调整大小时调整大小?

java - 编码风格的差异

Java 进程与线程的线程亲和性

java - RxJava。 Observable.delay 工作奇怪(最后缺少一些项目)

java - 如何在 Android 应用程序的单个数据库中创建两个表?