我有一个包含30个元素的arrayList。我想从这个列表中创建15个元素的许多子列表。这样做的有效方法是什么?
现在我克隆了ArrayList并使用remove(随机)来做,但我确信这太笨拙了。我该怎么做呢? Java是否具有像R?
中的“样本”函数
澄清:通过抽样而无需替换,我的意思是从原始列表中的30个中随机随机 15个唯一元素。此外,我希望能够反复这样做。
答案 0 :(得分:8)
使用Collections#shuffle
方法随机播放原始列表,并返回包含前15个元素的列表。
答案 1 :(得分:2)
考虑创建新列表并从当前列表中添加随机元素,而不是复制所有元素并将其删除。
另一种方法是在当前列表的顶部创建某种View
。
实现Iterator
接口,该接口在next
操作期间随机生成元素索引,并从当前列表中按索引检索元素。
答案 2 :(得分:1)
不,Java没有R中的示例函数。但是,可以编写这样的函数:
// Samples n elements from original, and returns that list
public <T> static List<T> sample(List<T> original, int n) {
List<T> result = new ArrayList<T>(n);
for (int i = 0; i < original.size(); i++) {
if (result.size() == n)
return result;
if ((n - result.size()) >= (original.size() - i)) {
result.add(original.get(i));
} else if (Math.random() < ((double)n / original.size())) {
result.add(original.get(i));
}
}
return result;
}
此函数遍历original
,并根据随机数将当前元素复制到result
,除非我们接近original
的末尾要求复制剩余的所有剩余elements(循环中的第二个if语句)。
答案 3 :(得分:0)
这是一个基本的组合学问题。您的列表中有30个元素,并且您想要选择15.如果订单很重要,您需要排列,如果无关紧要,则需要组合。
Web上有各种Java组合示例,它们通常使用combinadics。我不知道任何现成的Java库,但Apache Math Commons有二项式系数支持,以帮助您实现组合,如果你走这条路线。一旦你有一个从0到29的15个索引的序列,我建议创建一个只读迭代器,你可以从中读取元素。这样您就不必创建任何新列表或复制任何引用。