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


当前回答

你能不能得到集合/数组的大小/长度,生成一个介于0和大小/长度之间的随机数,然后调用索引与该数字匹配的元素?HashSet有一个.size()方法,我很确定。

在伪代码中-

function randFromSet(target){
 var targetLength:uint = target.length()
 var randomIndex:uint = random(0,targetLength);
 return target[randomIndex];
}

其他回答

Java 8+流:

    static <E> Optional<E> getRandomElement(Collection<E> collection) {
        return collection
                .stream()
                .skip(ThreadLocalRandom.current()
                .nextInt(collection.size()))
                .findAny();
    }

根据Joshua Bone的回答,但略有变化:

忽略Streams元素的顺序,以便在并行操作中略微提高性能 使用当前线程的ThreadLocalRandom 接受任何集合类型作为输入 返回提供的Optional而不是null

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

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

如果你不介意第三方库,Utils库有一个IterableUtils,它有一个randomFrom(Iterable Iterable)方法,该方法将接受一个Set并从中返回一个随机元素

Set<Object> set = new HashSet<>();
set.add(...);
...
Object random = IterableUtils.randomFrom(set);

它在Maven中央存储库中:

<dependency>
  <groupId>com.github.rkumsher</groupId>
  <artifactId>utils</artifactId>
  <version>1.3</version>
</dependency>
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++;
}

数学:

a = {1, 2, 3, 4, 5}

a[[ ⌈ Length[a] Random[] ⌉ ]]

或者,在最近的版本中,简单地说:

RandomChoice[a]

Random[]生成一个0到1之间的伪随机浮点数。它乘以列表的长度,然后使用ceiling函数四舍五入到下一个整数。该索引然后从。

由于哈希表功能在Mathematica中经常使用规则,并且规则存储在列表中,因此可以使用:

a = {"Badger" -> 5, "Bird" -> 1, "Fox" -> 3, "Frog" -> 2, "Wolf" -> 4};