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


当前回答

这比接受答案中的for-each循环要快:

int index = rand.nextInt(set.size());
Iterator<Object> iter = set.iterator();
for (int i = 0; i < index; i++) {
    iter.next();
}
return iter.next();

for-each构造在每次循环时调用Iterator.hasNext(),但由于index < set.size(),该检查是不必要的开销。我看到速度提高了10-20%,但是YMMV。(而且,编译时不需要添加额外的return语句。)

请注意,这段代码(以及大多数其他答案)可以应用于任何集合,而不仅仅是集合。通用方法形式:

public static <E> E choice(Collection<? extends E> coll, Random rand) {
    if (coll.size() == 0) {
        return null; // or throw IAE, if you prefer
    }

    int index = rand.nextInt(coll.size());
    if (coll instanceof List) { // optimization
        return ((List<? extends E>) coll).get(index);
    } else {
        Iterator<? extends E> iter = coll.iterator();
        for (int i = 0; i < index; i++) {
            iter.next();
        }
        return iter.next();
    }
}

其他回答

你也可以将set转换为数组use array 它可能会在小范围内工作,我看到for循环中投票最多的答案是O(n)

Object[] arr = set.toArray();

int v = (int) arr[rnd.nextInt(arr.length)];

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

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

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

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

在c#中

        Random random = new Random((int)DateTime.Now.Ticks);

        OrderedDictionary od = new OrderedDictionary();

        od.Add("abc", 1);
        od.Add("def", 2);
        od.Add("ghi", 3);
        od.Add("jkl", 4);


        int randomIndex = random.Next(od.Count);

        Console.WriteLine(od[randomIndex]);

        // Can access via index or key value:
        Console.WriteLine(od[1]);
        Console.WriteLine(od["def"]);

既然你说“其他语言的解决方案也欢迎”,下面是Python的版本:

>>> import random
>>> random.choice([1,2,3,4,5,6])
3
>>> random.choice([1,2,3,4,5,6])
4

你知道吗?

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