它看起来像我也不能使用ArrayList也没有一套:集合,没有重复,并在Java中
Set<>
- 我能避免使用一组重复,但没有洗牌的选项//Collections.shuffle(List<?> list)
ArrayList<>
- 我可以使用shuffle随机化列表,但允许重复。
我可以用一个Set
,并转换成ArrayList
(或者反过来),这样,避免了重复。或者,循环遍历集合以随机化项目。但我正在寻找更高效的东西。
它看起来像我也不能使用ArrayList也没有一套:集合,没有重复,并在Java中
Set<>
- 我能避免使用一组重复,但没有洗牌的选项//Collections.shuffle(List<?> list)
ArrayList<>
- 我可以使用shuffle随机化列表,但允许重复。
我可以用一个Set
,并转换成ArrayList
(或者反过来),这样,避免了重复。或者,循环遍历集合以随机化项目。但我正在寻找更高效的东西。
您可以维护两个单独的收藏,一个ArrayList
和一个HashSet
,并拒绝插入任何存在于HashSet
中的物品。
如果您关心封装,包住两个集合的元对象实现List
,并仔细记录重复的元素的插入会被拒绝,即使List
一般合同并没有规定这样。
说到这个解决方案的成本,我相信,在时间上,如果相比于普通ArrayList
成本是绝对可以忽略不计:大部分操作上HashSet
成本存在摊销O(1),即查找和插入。另一方面,您的内存使用量将是两次(或更多,具体取决于HashSet
加载因子)。
根据你对我的回答的评论,你的解决方案可能是最好的。但是我会提到O(1)重复检查。 – 2013-02-15 11:04:15
它有点争议。在某些情况下,HashSet中的插入可能会花费O(n)。但是我添加了它。 – gd1 2013-02-15 11:04:52
你也可以实现Set,并创建一个迭代器,以我想的随机顺序返回元素。 – 2013-02-15 11:07:24
据我所知套件没有订购,所以你显然不能洗牌套件。为了从列表中删除重复项,我找到了这个:How do I remove repeated elements from ArrayList?。
随着代码量最少,最优雅的气质,你可以这样做:
public void testFoo() {
Set<Integer> s = new TreeSet<Integer>();
s.add(2);
s.add(1);
s.add(3);
Collections.shuffle(Arrays.asList(s.toArray()));
}
但是,这不是很有效,你可以使用一个数组和哈希函数把元素所需位置在数组上,并且在放置它们之前检查它们是否已经存在,这将在O(n)时间内工作,所以它非常好,但需要更多的代码和一些关注散列函数。
其实你可以使用一个“有序集”,例如TreeSet中。为了得到一个随机顺序,不要插入实际的项目,而要插入一些随机权重的包装并使用相应的比较器。然而,重新洗牌将需要更新所有包装重量。
在添加它之前,您可以检查该项是否已存在于ArrayList中:myList.contains(myItem);这个检查只应该是O(n)。 – HectorLector 2013-02-15 10:56:07
*更有效率的东西*>您是否在说这是因为您已经(a)尝试过,并且(b)通过适当的基准测试得出结论,这是您的应用程序中的一个重大瓶颈?如果不是,请不要过早地优化并写出最清楚的版本(可能转换为数组列表)。 – 2013-02-15 10:57:42