我想要一个包含无序,可重复项目的集合。 在Java中,Set是不可重复的,List是有序的,这不是我想要的。
似乎Pool是一个合适的集合,但它并不存在于Java中。 界面应如下:
public interface Pool<T> {
void set(T item);
T get();
}
它存在于某个地方吗?
补充:
我意识到我的想法不正确。事实上,我希望有这样的界面:
public interface Pool<T> {
void put(T item);
T randomRemove();
}
也就是说,我希望每次都能得到一个项目。我怎样才能实现它?
答案 0 :(得分:4)
您可以通过打包Pool<T>
来实现List<T>
功能。
public class ListPool<T> implements Pool<T> {
private List<T> list = ArrayList<>();
public void put(T t) {
list.append(t);
}
public T randomRemove() {
return list.remove(rand.nextInt(list.size()));
}
}
由于remove
在标准O(N)
实施中List
,因此效率不高。但是,使用ArrayList
的替代实现有点复杂,但提供的randomRemove
为O(1)
。我们的想法是将列表视为动态数组并管理&#34; size&#34;自己。
这样的事情:
public class FasterPool<T> implements Pool<T> {
private List<T> list = new ArrayList<>();
private int size = 0;
Random rand = new Random();
public void put(T t) {
if (size == list.size()) {
list.append(t);
} else {
list.set(size, t);
size++;
}
public T randomRemove() {
int pos = rand.nextInt(size);
T result = list.get(pos);
if (pos < size - 1) {
list.set(pos, list.get(size - 1));
}
list.set(size - 1, null); // avoid memory leak ...
size--;
return result;
}
}
注意:当您尝试删除元素时,两个版本都不会处理池为空的情况。都没有编译或测试过。请相应地处理代码。
最后,如果您尝试使用未排序的集合类型来实现,那么您不太可能有效地删除随机元素。提示:删除集合的迭代器返回的第一个对于任何实际的集合数据结构都不是真正随机的。这也适用于(假设的)Bag
实施。
答案 1 :(得分:1)
如果您需要随机排序,应该采用一种方式收集洗牌。
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
Collections.shuffle(list);
System.out.println(list);
输出:
[B, A, C]