简体   繁体   English

PriorityQueue的意外行为删除:为什么不使用compareTo?

[英]Unexpected behavior with PriorityQueue remove: Why isn't compareTo used?

I am trying to use the priority queue, but the remove() is not working: My code: 我正在尝试使用优先级队列,但是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());

And the class implementation: 和类的实现:

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

I think the output final output should be 2, since I am removing the added '1'. 我认为输出最终输出应为2,因为我要删除添加的“ 1”。 The compareTo() should be used by priority queue remove() but his does not seem to be the case. 优先级队列remove()应该使用compareTo(),但事实并非如此。 What I am doing wrong? 我做错了什么? I know pq.remove(a) will work, but then my code should also work 我知道pq.remove(a)可以用,但是我的代码也可以用

remove() will not use compareTo() , rather it will use equals() to find the object to remove. remove()将不使用compareTo() ,而是将使用equals()查找要删除的对象。 You need to override equals() on your class as well. 您还需要在类上重写equals()

Edit: Javadoc for PriorityQueue (Thanks, @templatetypedef) 编辑: PriorityQueue Javadoc (谢谢,@ templatetypedef)

The PriorityQueue class's remove method has the following description: PriorityQueue类的remove方法具有以下描述:

Removes a single instance of the specified element from this queue, if it is present. 从该队列中删除指定元素的单个实例(如果存在)。 More formally, removes an element e such that o.equals(e) , if this queue contains one or more such elements. 更正式地说,如果此队列包含一个或多个这样的元素,则删除元素e,使其o.equals(e) Returns true if and only if this queue contained the specified element (or equivalently, if this queue changed as a result of the call). 当且仅当此队列包含指定的元素时(或等效地,如果此队列由于调用而更改),则返回true。

Thus compareTo is not used when determining whether to remove something. 因此,在确定是否remove某些内容时不使用compareTo I believe that this is because PriorityQueue implements Collection , and the behavior of remove must therefore be consistent with the behavior specified in Collection , which is 我相信这是因为PriorityQueue实现了Collection ,因此remove的行为必须与Collection指定的行为一致,即

Removes a single instance of the specified element from this collection, if it is present (optional operation). 如果存在,则从此集合中删除指定元素的单个实例(可选操作)。 More formally, removes an element e such that (o==null ? e==null : o.equals(e)), if this collection contains one or more such elements. 更正式地讲,如果此集合包含一个或多个这样的元素,则删除元素(e == null?e == null:o.equals(e))。

In other words, I believe this design decision is motivated by trying to fit PriorityQueue into the Collection framework, even though it is a bit odd. 换句话说,我认为此设计决定是通过尝试将PriorityQueue放入Collection框架中来进行的,即使有点奇怪。

Hope this helps! 希望这可以帮助!

Please note that PriorityQueue has an other constructor that takes a Comparator. 请注意,PriorityQueue还有一个采用Comparator的其他构造函数。 So it could be to keep the remove behavior consistent even if a Comparator is used or the objects in the priorityQueue implement the Comparable Interface, equals does not depend on any comparison except the base equals property of the Object. 因此,即使使用Comparator或priorityQueue中的对象实现了Comparable接口,也可能要使删除行为保持一致,除Object的基础equals属性外,equals不依赖于任何比较。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM