问题
Random类有一个在给定范围内生成随机int的方法。例如:
Random r = new Random();
int x = r.nextInt(100);
这将产生一个大于或等于0且小于100的int数。我想用长数做同样的事。
long y = magicRandomLongGenerator(100);
Random类只有nextLong(),但它不允许设置范围。
#1 热门回答(121 赞)
从Java 7(或Android API Level 21 = 5.0)开始,你可以直接使用ThreadLocalRandom.current().nextLong(n)
(对于0≤x<n)和ThreadLocalRandom.current().nextLong(m, n)
(对于m≤x<n)。有关详细信息,请参阅@Alex的答案。
如果你遇到Java 6(或Android 4.x),你需要使用外部库(例如,org.apache.commons.math3.random.RandomDataGenerator.getRandomGenerator().nextLong(0, n-1)
,请参阅@mawaldne的答案),或者实现你自己的nextLong(n)
。
根据http://java.sun.com/j2se/1.5.0/docs/api/java/util/Random.htmlnextInt
实现为
public int nextInt(int n) {
if (n<=0)
throw new IllegalArgumentException("n must be positive");
if ((n & -n) == n) // i.e., n is a power of 2
return (int)((n * (long)next(31)) >> 31);
int bits, val;
do {
bits = next(31);
val = bits % n;
} while(bits - val + (n-1) < 0);
return val;
}
所以我们可以修改它来执行nextLong
:
long nextLong(Random rng, long n) {
// error checking and 2^x checking removed for simplicity.
long bits, val;
do {
bits = (rng.nextLong() << 1) >>> 1;
val = bits % n;
} while (bits-val+(n-1) < 0L);
return val;
}
#2 热门回答(72 赞)
在一个范围内生成数字(没有实用方法)的标准方法是只使用范围为的double:
long range = 1234567L;
Random r = new Random()
long number = (long)(r.nextDouble()*range);
会给你一个0(含)和范围(独家)之间的长。同样,如果你想要一个介于x和y之间的数字:
long x = 1234567L;
long y = 23456789L;
Random r = new Random()
long number = x+((long)(r.nextDouble()*(y-x)));
会给你很长的1234567(含)到123456789(独家)
注意:检查括号,因为转换为long具有比乘法更高的优先级。
#3 热门回答(54 赞)
#ThreadLocalRandom
ThreadLocalRandom
是anextLong(long bound)
方法。
long v = ThreadLocalRandom.current().nextLong(100);
它还有nextLong(long origin, long bound)
如果你需要一个非0的原点。传递原点(包括)和界限(不包括)。
long v = ThreadLocalRandom.current().nextLong(10,100); // For 2-digit integers, 10-99 inclusive.
SplittableRandom
具有相同的99458567方法,如果你想要可重复的数字序列,则允许你选择种子。