java在每次调用时生成唯一的随机数
在一次采访中,我被要求编写一种方法,每次调用时都会生成唯一的5位随机数。例如:如果我调用该方法并得到22222,那么在下一次调用中,我不应该得到22222
我编写了如下代码:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class RandomNumberGen {
private static ArrayList arr=new ArrayList();
private static int k=-1;
public RandomNumberGen(){
for (int i=10000;i<99999;i++){
arr.add(i);
}
Collections.shuffle(arr);
}
public static void main(String[] args) {
for(int m=0;m<10;m++){
try {
System.out.println(new RandomNumberGen().randomNumbermethod());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public Integer randomNumbermethod() throws Exception{
k++;
if(k>=arr.size()){
throw new Exception("No more number available");
}else return (Integer) arr.get(k);
}
}
答案被接受了,但我现在被要求避免内存浪费。 我的问题就在这里,你可以看到我只用了10个数字。所以arraylist占用的其余空间是内存浪费。有没有一种方法可以在不使用额外内存的情况下完成同样的事情。 我的意思是,有一种方法可以在每次通话中生成唯一的号码,这样就不会浪费这么多的内存
# 1 楼答案
看起来很简单。一个更简单、内存使用更少的解决方案是,只需创建一个集合,它将保存所有您想要的数字,如下所示:
要查看所有这些内容:
这将保证集合属性的唯一性,并大大提高内存使用率
# 2 楼答案
影响:
生成的数字可以在集合中进行跟踪。这意味着每个号码有32位的开销(当跟踪可用或生成的号码时)加上收集开销。另一种可能是使用布尔数组并标记已使用的插槽。同样,这是一种开销,因为布尔值通常存储为32位值
但是有一种更便宜的存储布尔值的方法:将布尔值压缩成整数。这就是
java.util.BitSet
所做的,因此每个布尔值将占用一位使用
BitSet
解决方案并跟踪可用的号码数:# 3 楼答案
只是
编辑后:(编辑前不理解)-你可以把生成的数字放在
HashSet
中,然后随机检查集合是否包含新的数字(如果你多次使用它,它会变得非常慢,但我认为如果你不需要很多数字,这是一个很好的解决方案根据我的评论:在超过大约50%的数字后,我会创建一个剩余数字的集合,与你的一样,但你应该在课堂上记录,在50%的结果使用率后,它可以冻结片刻,并允许将此系数设置为客户端
也许有更好的方法,这取决于生成的数字中必须包含“多少随机性”(例如序列生成器的数学方法)
# 4 楼答案
# 5 楼答案
您的方法确实是创建大量唯一值的理想方法,但是,如果您只创建少量的唯一值,只需跟踪所使用的值以保证唯一性就可以更有效
当只需要一小部分可用范围时,这种方法非常有效,但随着碰撞变得越来越常见,这种方法变得越来越慢。您应该选择的具体实现在很大程度上取决于需要获得多少值
需要考虑的注意事项