声明一个`Random`对象作为私有的静态常量属性是否可以?

huangapple go评论90阅读模式
英文:

Is it okay to declare a Random object as a private static final attribute?

问题

我有以下的类:

public class CardGenerator {
    private static final Random random = new Random();

    private CardGenerator() {

    }

    public static long generateNumber() {
        int identifier = random.nextInt(1_000_000_000 - 100_000_000 + 1)
                                      + 100_000_000; //9位数字
        long number = 400_000 * 1_000_000_000L
                    + identifier; //15位数字
        int checksum = Luhn.getChecksum(number);
        number = number * 10 + checksum; //16位数字
        return number;
    }

    public static int generatePIN() {
        return random.nextInt(10_000 - 1_000 + 1) + 1_000; //4位数字
    }
}

或者在每个方法中创建一个新的Random对象是否更好?

英文:

I have the following class:

public class CardGenerator {
    private static final Random random = new Random();

    private CardGenerator() {

    }

    public static long generateNumber() {
        int identifier = random.nextInt(1_000_000_000 - 100_000_000 + 1)
                                      + 100_000_000; //9 digits
        long number = 400_000 * 1_000_000_000L
                    + identifier; //15 digits
        int checksum = Luhn.getChecksum(number);
        number = number * 10 + checksum; //16 digits
        return number;
    }

    public static int generatePIN() {
        return random.nextInt(10_000 - 1_000 + 1) + 1_000; //4 digits
    }
}

or is it better practice to create a new Random object in every method?

答案1

得分: 1

"更好" 的定义总是取决于您的具体要求。

需要考虑的因素有:

  • 您是否希望您的代码是可测试的(上述内容仅在一定程度上可测试)
  • 您是否希望您的代码在多线程环境中工作,并且不同线程是否应该看到相同的随机数

换句话说,要避免给出明确答案:您必须理解代码将被用于的约定。然后您可以决定什么是合适的。

上述内容在“仅用于单次练习后即丢弃”的情况下可能还可以,但不能用于更多情况。

英文:

"Better" always depends on your exact requirements.

The things to consider:

  • do you want your code to be testable (the above is only to a certain degree)
  • do you want your code to work in a multi threaded environment, and should the different threads see the same random numbers

In other words, the distinct non-answer: you have to understand the contract that your code will be used for. Then you can decide what is appropriate.

The above is probably okay on a "throw away after single exercise" level, but not more.

答案2

得分: 0

你可能会认为,生成一个新的随机对象可能会更加随机地创建数字。但事实并非如此。调用next()总是会更改用于创建随机数的种子。

protected int next(int bits) { // 被nextInt()调用
    long oldseed, nextseed;
    AtomicLong seed = this.seed;
    do {
        oldseed = seed.get();
        nextseed = (oldseed * multiplier + addend) & mask;
    } while (!seed.compareAndSet(oldseed, nextseed));
    return (int)(nextseed >>> (48 - bits));
}

因此,每次创建新的Random对象并不会带来任何优势,但由于您总是在创建新对象,性能稍微下降。

所以,是的,坚持使用一个Random对象是完全可以的。

英文:

You might be thinking, that generating a new Random object might create numbers more, eh, randomly. But this is not the case. Calling next() always changes the seed used to create random numbers.

protected int next(int bits) { // is called by nextInt()
    long oldseed, nextseed;
    AtomicLong seed = this.seed;
    do {
        oldseed = seed.get();
        nextseed = (oldseed * multiplier + addend) & mask;
    } while (!seed.compareAndSet(oldseed, nextseed));
    return (int)(nextseed >>> (48 - bits));
}

So you have no advantages in creating a new Random object each time but you have a bit less performance because you are always creating a new object.

So yes, it's totally okay to stick with one Random object.

huangapple
  • 本文由 发表于 2020年10月27日 21:59:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/64556095.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定