如何配置Java优先级队列以忽略重复项?

时间:2012-05-06 10:08:17

标签: java collections priority-queue

我认为add()应该忽略重复,但我的输出有重复。我怎么不存储重复项?

我还想知道优先级队列如何检查两个元素是否重复。我猜它正在使用比较器等于,但我只是想确定。

由于

5 个答案:

答案 0 :(得分:11)

以下是PriorityQueue Javadoc的一部分:

  

此队列根据构造时指定的顺序对元素进行排序,该顺序根据其自然顺序(请参阅Comparable)或根据比较器指定,具体取决于使用的构造函数。

所以,是的,PriorityQueue使用Comparator(如果您将其指定为构造函数参数)或使用compareTo(...)方法(元素必须实现Comparable接口)。

PriorityQueue允许重复。因此,如果您想避免这种情况,则需要实现自己的Queue版本。你可以找到非常优雅的方式,如何在"Effective Java", page 85中做到这一点。或者,您可以扩展PriorityQueue类并覆盖add方法(这是放置contains(...)检查的理想位置)。

答案 1 :(得分:6)

Java中的PriorityQueue对重复元素没有任何限制。如果要确保优先级队列中永远不会出现两个相同的项目,那么最简单的方法是与优先级队列并行维护单独的Set。每次要将元素插入优先级队列时,都可以检查集合是否已包含该元素,如果没有,则将其添加到集合和优先级队列中。每当从优先级队列中删除元素时,只需从集合中删除该元素。

或者,根据您打算在优先级队列上执行的操作以及在您的情况下如何定义相等性,将其替换为单个TreeSet可能是可行的,因为这仍然允许您执行您在优先级队列中可以访问的所有重要操作,同时另外不允许重复操作。

答案 2 :(得分:4)

import java.util.PriorityQueue;

public class NoDuplicates<E> extends PriorityQueue<E> 
{
    @Override
    public boolean offer(E e) 
    {
        boolean isAdded = false;
        if(!super.contains(e))
        {
            isAdded = super.offer(e);
        }
        return isAdded;
    }
    public static void main(String args[])
    {
        PriorityQueue<Integer> p = new NoDuplicates<Integer>();
        p.add(10);
        p.add(20);
        p.add(10);
        for(int i =0;i<=2;i++)
        {
            System.out.println(p.poll());
        }

    }
}

答案 3 :(得分:3)

集合是唯一忽略重复的东西。列表和队列没有。 (LinkedList是一个队列)

如果要删除重复项,可以检查所带的条目()是否与前一条相同并忽略它。您可以按照自己喜欢的方式进行比较。 ;)

答案 4 :(得分:0)

您可以创建一个哈希集并将哈希集的对象传递给优先级队列。 优先级队列的构造函数之一是

PriorityQueue q = new PriorityQueue(SortedSet s)

实现没有重复项的优先级队列的代码是

import java.util.Comparator;
import java.util.HashSet;
import java.util.PriorityQueue;

public class DatabaseConn {

    public static void main(String[] args) {

        HashSet<Integer> s = new HashSet<>();
        s.add(10);
        s.add(20);
        s.add(5);
        s.add(10);

        PriorityQueue<Integer> q = new PriorityQueue<>(s);  
        System.out.println(q);

    }

}