Java 从集合中获取随机条目
从集合中获取随机元素的最佳方法是什么?我听说过最好的迭代,所以我做了以下工作:Java 从集合中获取随机条目,java,Java,从集合中获取随机元素的最佳方法是什么?我听说过最好的迭代,所以我做了以下工作: Collection<Integer> c = new HashSet<Integer>(); Random r = new Random(); for (int i = 0; i < 100000; i++){ c.add(r.nextInt()); } Iterator<Integer> i = c.iterato
Collection<Integer> c = new HashSet<Integer>();
Random r = new Random();
for (int i = 0; i < 100000; i++){
c.add(r.nextInt());
}
Iterator<Integer> i = c.iterator();
int random = r.nextInt(c.size());
int num = 0;
int count = 1;
while(i.hasNext()){
num = i.next();
if (count == random){
break;
}
count++;
}
System.out.println(num);
Collection c=newhashset();
随机r=新随机();
对于(int i=0;i<100000;i++){
c、 添加(r.nextInt());
}
迭代器i=c.迭代器();
int random=r.nextInt(c.size());
int num=0;
整数计数=1;
while(i.hasNext()){
num=i.next();
如果(计数==随机){
打破
}
计数++;
}
系统输出打印项数(num);
据我所知,它工作正常,只需要几毫秒就可以完成。然而,有人告诉我,上述问题过于复杂了。我知道您可以将集合转换为数组,或者在Java 8中可以使用流。转换
集合,然后访问随机单元格可能会使代码更紧凑,但可能会降低代码的性能
让我们考虑下面的代码:<代码>集合>代码> >代码> toReals具有以下基本数据结构:
数组。有可能像System.arrayCopy
这样的东西可以用来在固定时间内进行这种转换
链表/树。在这种情况下,创建阵列几乎肯定需要线性时间。必须分配一个新的数组,然后通过遍历数据结构来填充它
在这两种情况下,通过先转换为数组,您还增加了额外的内存开销
一天结束时,了解算法将如何执行取决于预测Collection
实例类型的分布情况
如果您处理的是使用数组作为底层数据结构的集合
s,那么生成一个随机整数并访问该单元格需要(非常短的)固定时间
另一方面,如果基础数据结构是链表或树,则生成一个随机整数并访问该单元格可能需要线性时间
如果您对线性时间感到满意,那么您可能可以保留您的解决方案。如果您愿意通过限制可使用的集合
的类型来组合一个不太通用的解决方案,则可能会提高性能。转换集合
,然后访问随机单元格可能会使代码更紧凑,但可能会降低代码的性能
让我们考虑下面的代码:<代码>集合>代码> >代码> toReals具有以下基本数据结构:
数组。有可能像System.arrayCopy
这样的东西可以用来在固定时间内进行这种转换
链表/树。在这种情况下,创建阵列几乎肯定需要线性时间。必须分配一个新的数组,然后通过遍历数据结构来填充它
在这两种情况下,通过先转换为数组,您还增加了额外的内存开销
一天结束时,了解算法将如何执行取决于预测Collection
实例类型的分布情况
如果您处理的是使用数组作为底层数据结构的集合
s,那么生成一个随机整数并访问该单元格需要(非常短的)固定时间
另一方面,如果基础数据结构是链表或树,则生成一个随机整数并访问该单元格可能需要线性时间
如果您对线性时间感到满意,那么您可能可以保留您的解决方案。如果您愿意通过限制可使用的集合的类型来组合一个不太通用的解决方案,您可能会提高性能。放弃集合
;该接口不够灵活,无法让您按索引选择元素
放弃哈希集
<代码>设置
s通常不支持随机索引
你需要使用
列表
,并利用它来完成你感兴趣的事情。放弃收藏
;该接口不够灵活,无法让您按索引选择元素
放弃哈希集<代码>设置s通常不支持随机索引
您需要使用
列表
,并利用来完成您感兴趣的内容。集合
不允许通过索引直接访问元素。它是JDK集合类最通用的接口,因此涵盖了有序列表和无序列表
如果您坚持使用集合
界面,类似这样的功能应该可以工作,它与您的代码类似,但更通用:
public static <T> T getRandomElement(Collection<T> c) {
int random = (int) (Math.random() * c.size());
Iterator<T> it = c.iterator();
for (int i = 0; i < random; i++) {
it.next();
}
return it.next();
}
publicstatict getrandom元素(集合c){
int random=(int)(Math.random()*c.size());
迭代器it=c.Iterator();
for(int i=0;i
但是,您应该问问自己,在您的情况下,是否可以使用
列表
界面,因为它允许使用get
方法通过(随机)索引进行简单访问。集合
不允许通过索引直接访问元素。它是JDK集合类最通用的接口,因此涵盖了有序列表和无序列表
如果您坚持使用集合
界面,类似这样的功能应该可以工作,它与您的代码类似,但更通用:
public static <T> T getRandomElement(Collection<T> c) {
int random = (int) (Math.random() * c.size());
Iterator<T> it = c.iterator();
for (int i = 0; i < random; i++) {
it.next();
}
return it.next();
}
publicstatict getrandom元素(集合c){
int random=(int)(Math.random()*c.size());
迭代器it=c.Iterator();
for(int i=0;i
然而,你应该问你的