Неожиданное поведение при удалении PriorityQueue: почему не используется сравнение? - PullRequest
1 голос
/ 18 января 2012

Я пытаюсь использовать приоритетную очередь, но метод remove () не работает: Мой код:

PriorityQueue<OwnClass> pq=new PriorityQueue<OwnClass>();
OwnClass a=new OwnClass(1);
OwnClass b=new OwnClass(2);
OwnClass c=new OwnClass(3);
pq.add(a);
pq.add(b);
pq.add(c);
System.out.println("head:"+pq.peek());
pq.remove(new OwnClass(1));
System.out.println(pq.peek());

И класс реализации:

class OwnClass implements Comparable{

    int x;

    public OwnClass(int x){
        this.x=x;
    }

    public int compareTo(Object arg0) {

        OwnClass a=(OwnClass) arg0;
        if(a.x>this.x)
            return -1;
        if(a.x<x)
            return 1;
        return 0;
    }

    public String toString(){
        return ""+x;        
    }
}

Я думаю, что конечный результат вывода должен быть 2, так как я удаляю добавленную '1'. CompareTo () должно использоваться приоритетной очередью remove (), но его, похоже, нет. Что я делаю не так? Я знаю, что pq.remove (a) будет работать, но тогда мой код также должен работать

Ответы [ 3 ]

8 голосов
/ 18 января 2012

remove() не будет использовать compareTo(), скорее он будет использовать equals(), чтобы найти объект для удаления.Вам также необходимо переопределить equals() в своем классе.

Редактировать: Javadoc для PriorityQueue (Спасибо, @templatetypedef)

2 голосов
/ 19 января 2012

Обратите внимание, что у PriorityQueue есть другой конструктор, который использует Comparator. Таким образом, может быть поддержание согласованного поведения при удалении, даже если используется Comparator или объекты в priorityQueue реализуют Comparable Interface, equals не зависит ни от какого сравнения, за исключением свойства base equals объекта.

2 голосов
/ 18 января 2012

Метод remove класса PriorityQueue имеет следующее описание:

Удаляет один экземпляр указанного элемента из этой очереди, если он присутствует. Более формально, удаляет элемент e такой, что o.equals(e), если эта очередь содержит один или несколько таких элементов. Возвращает true, если и только если эта очередь содержала указанный элемент (или, что эквивалентно, если эта очередь изменилась как результат звонка).

Таким образом, compareTo не используется при определении, следует ли remove что-либо. Я считаю, что это потому, что PriorityQueue реализует Collection, и поэтому поведение remove должно соответствовать поведению, указанному в Collection, то есть

Удаляет один экземпляр указанного элемента из этой коллекции, если он присутствует (необязательная операция). Более формально, удаляет элемент e такой, что (o == null? E == null: o.equals (e)), если эта коллекция содержит один или несколько таких элементов.

Другими словами, я считаю, что это дизайнерское решение мотивировано попыткой вписать PriorityQueue в структуру Collection, хотя это немного странно.

Надеюсь, это поможет!

...