2014-02-11 223 views
1

我有一个ArrayList,我想从中获取一个随机值。要做到这一点,我想到了两个简单的方法:随机与随机

方法1:使用Random生成介于0和ArrayList大小的随机数,然后使用该号码arrayList.get(x)

方法2:使用arrayList.shuffle(),然后arrayList.get(0)

在随机性方面,一种方法比另一种方法更可取,我知道一个方法不可能是真正随机的,但我希望结果尽可能随机。

编辑:我只需要从ArrayList

+0

这两种方法都是可以接受的,我想。 –

回答

9

这取决于上下文。洗牌的

优点:

  • 一旦洗牌,然后就连续抓
  • 没有重复的值

优点随机的:

  • 伟大的少量值
  • 可以重复val UE的
+0

我做了一个编辑,说明我只需要一个值,而我只需要这个值一次。 –

+0

@ rsay3:你会需要另一个随机值或有没有考虑以前的值?如:在下一个必须选择的值是否可以选择一次?如果没关系:看看你想要多少。如果你仍然只需要一小笔钱,那么答案是随机的。如果你需要少量但唯一的值,那么你可以采用单独的列表和一些if语句来进行随机化,但是如果仅仅对整个列表进行洗牌并且完成它,那么你应该这样做。 –

+0

我的意思是我不需要任何其他的价值。我只想从ArrayList得到一个值,然后代码段完成 –

1

一个值,我要说的是随机数的选择是最好的(方法1)。

改变对象会占用额外的资源,因为它必须移动ArrayList中的所有对象,其中生成一个随机数可以产生相同的效果,而无需使用CPU时间循环访问数组元素!

此外,一定要生成一个介于0和大小MINUS ONE之间的数字。 :)

1

如果你只是想一个随机选择,使用方法1.如果你想获得随机选择的序列,没有重复,使用方法2

3

要回答你直接的问题:没有之一这些比另一个“更随机”。两种方法的结果在统计学上是不可区分的。毕竟,洗牌数组的第一步是(基本上)选取0N-1之间的数字(其中N是数组的长度)并将该元素移动到第一个位置。

也就是说,根据您的具体需求,有理由选择一个或另一个。 Jeroen's answer总结得很好。

0

随机性取决于两个因素,即算法(也称为“生成器”)和种子。

  • 每种方法使用哪些生成器?

第二次超载Collections.Shuffle()实际上接受种子Random。如果您选择默认过载,则使用Random,正如Javadoc中指定的。无论如何,你正在使用Random

  • 发电机是不同的?

另一个看看Javadoc中的随机数表明,除非你指定一个种子,否则它会播种一段时间的值。如果您查看实施,Shuffle不会指定时间。除非指定一个,否则您正在使用默认种子。

因为两者都使用Random并且两者使用相同的默认种子,所以它们是等同随机

  • 哪一个具有较高的时间复杂度?

改序列表是O(n)(Shuffle的Javadoc实际上指定了线性时间)。 Random.nextInt()的时间复杂度为O(1)。很明显,后者在只需要一个值的情况下更快。