英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论