如何从集合中随机选取一个元素? 我特别感兴趣的是从a中随机选取一个元素 Java中的HashSet或LinkedHashSet。 也欢迎其他语言的解决方案。


当前回答

上述解决方案从延迟的角度讲,但不能保证每个索引被选中的概率相等。 如果需要考虑这一点,可以尝试储层取样。http://en.wikipedia.org/wiki/Reservoir_sampling。Collections.shuffle()(正如少数人建议的那样)使用这样的算法。

其他回答

Icon有一个集合类型和一个随机元素操作符,一元“?”,因此表达式

? set( [1, 2, 3, 4, 5] )

将产生1到5之间的随机数。

当程序运行时,随机种子被初始化为0,因此要在每次运行时产生不同的结果,请使用randomize()

int size = myHashSet.size();
int item = new Random().nextInt(size); // In real life, the Random object should be rather more shared than this
int i = 0;
for(Object obj : myhashSet)
{
    if (i == item)
        return obj;
    i++;
}

如果设置的大小不是很大,那么使用数组可以做到这一点。

int random;
HashSet someSet;
<Type>[] randData;
random = new Random(System.currentTimeMillis).nextInt(someSet.size());
randData = someSet.toArray();
<Type> sResult = randData[random];

你知道吗?

在java.util.Collections中有一些有用的方法用于洗牌整个集合:collections .shuffle(List<?>)和collections .shuffle(List<?>列表,随机rnd)。

如果您希望在Java中执行此操作,则应该考虑将元素复制到某种随机访问集合(例如ArrayList)中。因为,除非你的集合很小,否则访问所选元素的代价会很高(O(n)而不是O(1))。[ed: list copy也是O(n)]

或者,您可以寻找另一个更符合您需求的Set实现。来自公共集合的ListOrderedSet看起来很有前途。