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

我希望集合包含无序、可重复的项目。 在Java中,集合是不可重复的,列表是有序的,这不是我想要的

看起来Pool是一个合适的集合,但它在Java中并不存在。 接口应如下所示:

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;
    }
}