Wit*_*rba 30
使用Lambdas,您可以非常快速地执行此操作,并在Collection为空时处理该情况.
public static <E> Optional<E> getRandom (Collection<E> e) {
return e.stream()
.skip((int) (e.size() * Math.random()))
.findFirst();
}
Run Code Online (Sandbox Code Playgroud)
Pet*_*rey 24
最有效的只能根据您的需要进行迭代.
public static <T> T random(Collection<T> coll) {
int num = (int) (Math.random() * coll.size());
for(T t: coll) if (--num < 0) return t;
throw new AssertionError();
}
Run Code Online (Sandbox Code Playgroud)
private Object getRandomObject(Collection from) {
Random rnd = new Random();
int i = rnd.nextInt(from.size());
return from.toArray()[i];
}
Run Code Online (Sandbox Code Playgroud)
我知道这是一个旧线程,但令我惊讶的是没有人提到将实现RandomAccess标记List为通过索引进行非常快速访问的接口。
这是RandomAccess的文档:
List 实现使用标记接口来指示它们支持快速(通常是恒定时间)随机访问。该接口的主要目的是允许通用算法改变其行为,以便在应用于随机或顺序访问列表时提供良好的性能。
例如: 它是通过ArrayList对比实现的LinkedList。
这是我利用它的解决方案:
public static <E> E getRandomElement(Collection<E> collection)
{
if(collection.isEmpty())
throw new IllegalArgumentException("Cannot return a random value from an empty collection!");
int randomIndex = ThreadLocalRandom.current().nextInt(collection.size());
if(collection instanceof RandomAccess)
return ((List<E>) collection).get(randomIndex);
for(E element : collection)
{
if(randomIndex == 0)
return element;
randomIndex--;
}
throw new IllegalStateException("How did we get here?"); //unreachable
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22728 次 |
| 最近记录: |