Java 使用比较器的LinkedBlockingQueue

Java 使用比较器的LinkedBlockingQueue,java,queue,comparator,Java,Queue,Comparator,我正在使用LinkedBlockingQueue在线程之间共享一些对象。 问题是我可以在这个队列中有一些重复项。 我尝试过这个解决方案: SortedSet<ResultInsert> set = new TreeSet<ResultInsert>(new MyComparator()); set.addAll(bulkInserts); 出于某种原因,它似乎没有将我的集合中的每个元素与所有元素进行比较。 例如,我有61个元素,它消除了一些重复,我有51个元素,除了这5

我正在使用
LinkedBlockingQueue
在线程之间共享一些对象。 问题是我可以在这个队列中有一些重复项。 我尝试过这个解决方案:

SortedSet<ResultInsert> set = new TreeSet<ResultInsert>(new MyComparator());
set.addAll(bulkInserts);
出于某种原因,它似乎没有将我的集合中的每个元素与所有元素进行比较。 例如,我有61个元素,它消除了一些重复,我有51个元素,除了这51个元素之间还有一些重复

我刚刚做了一个测试:对于61个对象,它调用比较342次,351次,。。不是每次都有相同的次数。 我把所有的都记录下来了,但我不明白。这并不是所有人都可以比较的


有人知道吗?从今天早上开始,我一直在试图解决这个问题,我不能再进一步了。

您当然可以创建自己的子类,通过覆盖
put
来防止重复的插入,如果队列中存在给定元素,则忽略调用

class NoDupBlockingQueue<T> extends LinkedBlockingQueue<T> {
    @Override
    public void put(T e) throws InterruptedException {
        if (!contains(e))
            super.put(e);
    }
}

请注意,向队列中添加元素将成为一个线性操作。如果希望获得更好的性能,您必须维护一个单独的数据结构(如哈希集)。

当然,您可以创建自己的子类,通过覆盖
put
来防止重复的插入,如果队列中存在给定的元素,只需忽略调用即可

class NoDupBlockingQueue<T> extends LinkedBlockingQueue<T> {
    @Override
    public void put(T e) throws InterruptedException {
        if (!contains(e))
            super.put(e);
    }
}

请注意,向队列中添加元素将成为一个线性操作。如果希望获得更好的性能,则必须维护一个单独的数据结构(如哈希集)。

解决此问题并非易事。您可以尝试使用
Maps.newSetFromMap(ConcurrentHashMap)
来近似使用
ConcurrentHashSet
,然后将其与队列结合使用……但我会花一两个小时来尝试通过允许重复来避免所有这些问题。解决此问题不是一个简单的方法。您可以尝试使用
Maps.newSetFromMap(ConcurrentHashMap)
来近似使用
ConcurrentHashSet
,然后将其与队列结合使用……但我会花一两个小时来尝试通过允许重复来避免所有这些问题。谢谢您的想法。我试过了,但由于某些原因,它不起作用。由于某些原因,它不能消除重复项。不,我在试别的东西。从ArrayList构建哈希集并执行addAll()。我用的是我自己的比较仪,但我不明白。它不会比较所有的元素。它消除了一些,但不是全部。我试着记录所有的元素,但它似乎没有比较它们之间的所有元素。你不能将比较器与HashSet一起使用。您需要依赖hashCode/equals。您的意思是我必须在自定义比较器中使用其他东西而不是树集?谢谢您的想法。我试过了,但由于某些原因,它不起作用。由于某些原因,它不能消除重复项。不,我在试别的东西。从ArrayList构建哈希集并执行addAll()。我用的是我自己的比较仪,但我不明白。它不会比较所有的元素。它消除了一些,但不是全部。我试着记录所有的元素,但它似乎没有比较它们之间的所有元素。你不能将比较器与HashSet一起使用。您需要依赖hashCode/equals。您的意思是我必须在自定义比较器中使用其他东西而不是树集?
class NoDupBlockingQueue<T> extends LinkedBlockingQueue<T> {

    Comparator<T> comp;

    public NoDupBlockingQueue(Comparator<T> comp) {
        this.comp = comp;
    }

    @Override
    public void put(T e) throws InterruptedException {
        for (T e2 : this)
            if (comp.compare(e, e2) == 0)
                return;
        super.put(e);
    }
}