我如何让一个PriorityQueue对我想要它排序的东西进行排序?

另外,在提供和添加方法之间有区别吗?


当前回答

从队列API:

offer方法尽可能插入一个元素,否则返回false。这与合集不同。方法,该方法只能通过抛出未经检查的异常来添加元素。offer方法设计用于故障是正常情况,而不是异常情况,例如在固定容量(或“有界”)队列中。

其他回答

我还想知道打印订单的问题。举个例子:

对于优先级队列:

PriorityQueue<String> pq3 = new PriorityQueue<String>();

这段代码:

pq3.offer("a");
pq3.offer("A");

可能打印不同于:

String[] sa = {"a", "A"}; 
for(String s : sa)   
   pq3.offer(s);

我从另一个论坛的讨论中找到了答案,其中一个用户说,“offer()/add()方法只将元素插入队列。如果你想要一个可预测的顺序,你应该使用peek/poll来返回队列的头。”

从队列API:

offer方法尽可能插入一个元素,否则返回false。这与合集不同。方法,该方法只能通过抛出未经检查的异常来添加元素。offer方法设计用于故障是正常情况,而不是异常情况,例如在固定容量(或“有界”)队列中。

作为使用Comparator的替代方法,您还可以让您在PriorityQueue中使用的类实现Comparable(并相应地重写compareTo方法)。

注意,如果排序是对象的直观排序,那么通常最好只使用Comparable而不是Comparator——例如,如果您有一个用例要按年龄对Person对象排序,那么可能最好只使用Comparator。

import java.lang.Comparable;
import java.util.PriorityQueue;

class Test
{
    public static void main(String[] args)
    {
        PriorityQueue<MyClass> queue = new PriorityQueue<MyClass>();
        queue.add(new MyClass(2, "short"));
        queue.add(new MyClass(2, "very long indeed"));
        queue.add(new MyClass(1, "medium"));
        queue.add(new MyClass(1, "very long indeed"));
        queue.add(new MyClass(2, "medium"));
        queue.add(new MyClass(1, "short"));
        while (queue.size() != 0)
            System.out.println(queue.remove());
    }
}
class MyClass implements Comparable<MyClass>
{
    int sortFirst;
    String sortByLength;

    public MyClass(int sortFirst, String sortByLength)
    {
        this.sortFirst = sortFirst;
        this.sortByLength = sortByLength;
    }

    @Override
    public int compareTo(MyClass other)
    {
        if (sortFirst != other.sortFirst)
            return Integer.compare(sortFirst, other.sortFirst);
        else
            return Integer.compare(sortByLength.length(), other.sortByLength.length());
    }

    public String toString()
    {
        return sortFirst + ", " + sortByLength;
    }
}

输出:

1, short
1, medium
1, very long indeed
2, short
2, medium
2, very long indeed

只是为了回答add() vs offer()问题(因为另一个问题在我看来已经完美回答了,这可能不是):

根据接口Queue上的JavaDoc,“offer方法尽可能插入一个元素,否则返回false。这与合集不同。方法,该方法只能通过抛出未经检查的异常来添加元素。offer方法设计用于故障是正常情况,而不是异常情况,例如在固定容量(或“有界”)队列中。”

That means if you can add the element (which should always be the case in a PriorityQueue), they work exactly the same. But if you can't add the element, offer() will give you a nice and pretty false return, while add() throws a nasty unchecked exception that you don't want in your code. If failure to add means code is working as intended and/or it is something you'll check normally, use offer(). If failure to add means something is broken, use add() and handle the resulting exception thrown according to the Collection interface's specifications.

它们都是通过这种方式实现的,以便在Queue接口上通过返回false(在有容量限制的队列中首选的方法)来指定offer()失败,并在Collection接口上通过抛出异常来维护add()总是失败的契约。

无论如何,希望这至少澄清了问题的那一部分。

没有区别,正如在javadoc中声明的那样:

public boolean add(E e) {
    return offer(e);
}