Java中是否存在无序的、可重复的集合类?
我希望集合包含无序、可重复的项目。 在Java中,集合是不可重复的,列表是有序的,这不是我想要的 看起来Pool是一个合适的集合,但它在Java中并不存在。 接口应如下所示:Java中是否存在无序的、可重复的集合类?,java,collections,Java,Collections,我希望集合包含无序、可重复的项目。 在Java中,集合是不可重复的,列表是有序的,这不是我想要的 看起来Pool是一个合适的集合,但它在Java中并不存在。 接口应如下所示: public interface Pool<T> { void set(T item); T get(); } 公共接口池{ 无效集(T项); T get(); } 它存在于某处吗 补充: 我意识到我表达的想法是错误的。事实上,我想要一个这样的界面: public interface Po
public interface Pool<T> {
void set(T item);
T get();
}
公共接口池{
无效集(T项);
T get();
}
它存在于某处吗
补充: 我意识到我表达的想法是错误的。事实上,我想要一个这样的界面:
public interface Pool<T> {
void put(T item);
T randomRemove();
}
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;
}
}
公共接口池{
无效认沽权(T项);
T随机删除();
}
也就是说,我每次都想得到一件物品。我怎样才能做到呢?你似乎在描述番石榴,更具体地说 JavaSE中不存在这样的集合,尽管您可以相当容易地构建自己的集合,这取决于您想要的功能量。基本上你会有一个
HashMap
或者类似的东西
举个例子:
class MultiSet<T> {
Map<T, Integer> map = new HashMap<>();
void add(T obj) {
Integer count = map.get(obj);
if (count == null) {
map.put(obj, 1);
} else {
map.put(obj, count + 1);
}
}
void remove(T obj) {
Integer count = map.get(obj);
if (count != null) {
if (count > 1) {
map.put(obj, count - 1);
} else {
map.remove(obj);
}
}
}
boolean contains(Object obj) {
return map.containsKey(obj);
}
}
类多集{
Map Map=newhashmap();
无效添加(T obj){
整数计数=map.get(obj);
如果(计数=null){
地图放置(obj,1);
}否则{
映射放置(对象,计数+1);
}
}
清除空隙(T obj){
整数计数=map.get(obj);
如果(计数!=null){
如果(计数>1){
map.put(obj,count-1);
}否则{
地图删除(obj);
}
}
}
布尔包含(对象obj){
返回地图。集装箱箱(obj);
}
}
如果您需要随机排序,一种方法应该是收集洗牌
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
Collections.shuffle(list);
System.out.println(list);
您可以通过包装
列表
来实现池
功能
注意:当您尝试删除元素时,这两个版本都不能处理池为空的情况。两者都没有经过编译或测试。请相应地对待代码
最后,如果尝试使用未排序的集合类型实现,则不太可能有效地删除随机元素。提示:对于任何实际的集合数据结构,删除集合迭代器返回的第一个不会是真正随机的。这也适用于一个(假设的)
Bag
实现。试试guava库。这个接口实际上是赤裸裸的。set
和get
应该是什么?set
“放入T
”和get
“移除并返回T
”?如果是这样的话,大多数有序的集合都支持add
和remove
或pop
的一些变体。您寻找一个明显无序的集合有什么特别的原因吗?被订购似乎不是一个障碍。番石榴的HashMultiset
是你想要的链接Multiset
源代码]它应该实现Iterable
甚至集合。现在我们有了Java 8,您可以显著地整理代码了。@BoristeSpider Java 8对整洁有什么帮助?@jinge将Map.ComputeFabSent
和Map.merge
结合起来,使大部分代码都是线性的。另外,计数器
是不必要的。通过创建一个额外的对象来避免装箱-不确定这真的有什么帮助。在FasterPool
代码段中,如果我们在随机位置将元素与最后一个元素交换,然后删除最后一个元素,我们就不能不管理自己的大小
,答案很好。但是我突然想到了一个问题,当你和他们中的一些人交换位置时,每件物品的概率是否总是一致的。那会有用的。@jinge-是的。在每个阶段,您都使用均匀分布的PRNG从“数组”中选择一个元素。元素位于数组中不同位置的事实并不影响这一点。
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()));
}
}
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;
}
}