从集合中获取随机条目

时间:2016-01-06 16:53:01

标签: java

从集合中获取随机元素的最佳方法是什么?我听过最好的迭代,所以我做了以下几点:

[mysqld] 
max_connections = xxx

据我所知,它工作正常,只需几毫秒即可完成。但是,我被告知上述问题过于复杂。我知道你可以将集合转换为数组,或者在Java 8中你可以使用流。

3 个答案:

答案 0 :(得分:0)

转换Collection to an array然后访问随机单元格可能会产生更紧凑的代码,但性能可能会降低。

让我们考虑一下您要转换Collection的{​​{1}}具有以下基础数据结构的情况:

  1. 阵列。可能会使用像toArray之类的东西在恒定时间内进行此转换。
  2. 链表/树。在这种情况下,创建数组几乎肯定需要线性时间。必须分配一个新数组,然后通过遍历数据结构来填充。
  3. 在任何一种情况下,您还通过先转换为数组来增加额外的内存开销。

    在一天结束时,了解算法的执行方式取决于预测您希望处理的System.arrayCopy实例类型的分布。

    如果您正在处理使用数组作为基础数据结构的Collection,则生成随机整数并访问该单元格应该花费(非常短的)恒定时间。

    另一方面,如果您的基础数据结构是链接列表,或树,那么生成随机整数并访问该单元格可能需要线性时间!

    如果您对线性时间感到满意,那么您可以将解决方案保留为原样。如果您愿意通过限制可以使用的Collection类型来整合解决方案,那么您可能会提高性能。

答案 1 :(得分:0)

放弃Collection;界面不够灵活,无法按索引选择元素。

放弃HashSet; Set一般不支持随机索引。

您需要使用List,并使用Collections#shuffle来完成您感兴趣的内容。

答案 2 :(得分:0)

Collection不允许按索引直接访问元素。它是JDK集合类的最通用接口,因此涵盖了有序和无序列表。

如果你坚持使用Collection界面,那么这样的东西应该有效,这与你的代码相似但更通用:

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();
}

但是你应该问自己,在你的情况下是否可以使用List接口,因为它允许使用get方法通过(随机)索引进行简单访问。

相关问题