Как настроить очередь приоритетов Java для игнорирования дубликатов?

Я думал, что add () должен игнорировать дубликаты, но мой вывод имеет дубликаты. Как не хранить дубликаты?

Я также хотел бы знать, как приоритетная очередь проверяет, дублируются ли два элемента. Я предполагаю, что он использует компаратор equals, но я просто хочу быть уверенным.

спасибо

5 ответов


вот часть из PriorityQueue Javadoc:

эта очередь упорядочивает элементы в соответствии с порядком, заданным во время построения, который задается либо в соответствии с их естественным порядком (см. Comparable), либо в соответствии с компаратором, в зависимости от того, какой конструктор используется.

Итак, да, PriorityQueue использует Comparator (если вы указали его как аргумент конструктора) или использует compareTo (...) метод (элементы должны реализовываться Comparable интерфейс).

PriorityQueue позволяет дубликаты. Поэтому, если вы хотите избежать этого, вам нужно реализовать свою собственную версию очереди. Вы можете найти очень элегантный способ, как это сделать в "эффективная Java", страница 85. В качестве альтернативы вы можете расширить класс PriorityQueue и переопределить метод add (это идеальное место для размещения contains(...) проверять.)


A PriorityQueue в Java нет никаких ограничений в отношении повторяющихся элементов. Если вы хотите убедиться, что два одинаковых элемента никогда не присутствуют в очереди приоритетов одновременно, самым простым способом было бы поддерживать отдельный Set параллельно с очередью приоритетов. Каждый раз, когда вы хотите вставить элемент в очередь приоритетов, вы можете проверить, содержит ли набор его уже, если нет, то добавьте его как в набор, так и в очередь приоритетов. Всякий раз, когда вы удаляете элемент из затем очередь приоритетов просто удаляет этот элемент из набора.

альтернативно, в зависимости от того, какие операции вы собираетесь выполнять в очереди приоритетов и как равенство определяется в вашем случае, может быть целесообразно заменить его одним TreeSet вместо этого, так как это все равно позволит вам выполнять все важные операции, к которым у вас будет доступ в очереди приоритетов, в то время как он дополнительно не разрешает дубликаты.


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

    }
}

наборы-это единственные вещи, которые игнорируют дубликаты. Списки и очереди нет. (LinkedList-это очередь)

Если вы хотите удалить дубликаты, вы можете проверить, совпадает ли запись, которую вы берете (), с предыдущей и игнорировать ее. Вы можете сравнивать так, как вам нравится. ;)


вы можете создать хэш-набор и передать объект хэш-набора в очередь приоритетов. Одним из конструкторов приоритетной очереди является

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

    }

}