我如何使用PriorityQueue?

我如何获得一个PriorityQueuesorting我想要它sorting?

另外, offeradd方法之间有区别吗?

使用带有Comparator<? super E> comparator的构造函数重载 Comparator<? super E> comparator并传入一个比较器,以适当的方式比较你的sorting顺序。 如果您举例说明如何sorting,那么如果您不确定,可以提供一些示例代码来实现比较器。 (虽然这很简单。)

正如其他地方所说: offeradd只是不同的接口方法实现。 在我得到的JDK源代码中add电话offer 。 虽然addoffer通常具有潜在的不同行为,因为offer能力由于大小限制而不能被添加,但是这种差异在无边界的PriorityQueue中是不相关的。

以下是按string长度sorting的优先级队列示例:

 // Test.java import java.util.Comparator; import java.util.PriorityQueue; public class Test { public static void main(String[] args) { Comparator<String> comparator = new StringLengthComparator(); PriorityQueue<String> queue = new PriorityQueue<String>(10, comparator); queue.add("short"); queue.add("very long indeed"); queue.add("medium"); while (queue.size() != 0) { System.out.println(queue.remove()); } } } // StringLengthComparator.java import java.util.Comparator; public class StringLengthComparator implements Comparator<String> { @Override public int compare(String x, String y) { // Assume neither string is null. Real code should // probably be more robust // You could also just return x.length() - y.length(), // which would be more efficient. if (x.length() < y.length()) { return -1; } if (x.length() > y.length()) { return 1; } return 0; } } 

这是输出:

确实很长

只要通过适当的Comparator器的构造函数 :

 PriorityQueue(int initialCapacity, Comparator<? super E> comparator) 

offeradd之间的唯一区别是它们所属的接口。 offer属于Queue<E> ,而add是原来在Collection<E>界面中看到的。 除了这两个方法完全相同的事情 – 插入指定的元素到优先队列。

来自Queue API :

如果可能,offer方法插入一个元素,否则返回false。 这与Collection.add方法不同,后者可能无法仅通过抛出未经检查的exception来添加元素。 报价方法是为故障是正常的情况而devise的,而不是例外情况,例如在固定容量(或“有界”)的队列中。

没有什么不同,正如在javadoc中声明:

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

我们可以使用Java 8中引入的lambda expression 。如果我们在Priority Queue中存储了一些String值,我们可以提供内嵌比较器:

 public static void main(String[] args) { PriorityQueue<String> pq= new PriorityQueue<String>(5, (a,b) -> a.length() - b.length()); pq.add("Apple"); pq.add("PineApple"); pq.add("Custard Apple"); while (pq.size() != 0) { System.out.println(pq.remove()); } } 

这将打印:

 Apple PineApple Custard Apple 

要颠倒顺序(将其更改为最大优先级队列),只需更改内联比较器中的顺序即可。

offer()vs add()

根据文件

如果可能,offer方法插入一个元素,否则返回false。 这与Collection.add方法不同,后者可能无法仅通过抛出未经检查的exception来添加元素。 报价方法是为故障是正常的情况而devise的,而不是例外情况,例如在固定容量(或“有界”)的队列中。

当使用容量受限的队列时,offer()通常比add()更可取,只能通过抛出exception来插入元素。 PriorityQueue是一个基于优先级堆的无限优先级队列。

在这里,我们可以定义用户定义的比较器:

下面的代码:

  import java.util.*; import java.util.Collections; import java.util.Comparator; class Checker implements Comparator<String> { public int compare(String str1, String str2) { if (str1.length() < str2.length()) return -1; else return 1; } } class Main { public static void main(String args[]) { PriorityQueue<String> queue=new PriorityQueue<String>(5, new Checker()); queue.add("india"); queue.add("bangladesh"); queue.add("pakistan"); while (queue.size() != 0) { System.out.printf("%s\n",queue.remove()); } } } 

输出:

  india pakistan bangladesh 

提供和添加方法之间的区别: 链接

我也想知道打印顺序。 考虑这种情况,例如:

对于优先队列:

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

此代码:

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

可能会打印不同于:

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

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

只是回答add() VS offer()问题(因为另一个是完美的回答,这可能不是):

根据接口Queue上的JavaDoc ,“offer方法在可能的情况下插入一个元素,否则返回false。这不同于Collection.add方法,它只能抛出未经检查的exception才能添加元素。当故障是正常情况时使用,而不是例外情况,例如在固定容量(或“有界”)队列中使用。

这意味着如果您可以添加元素(应始终是PriorityQueue中的情况),它们的工作原理完全相同。 但是如果你不能添加这个元素,那么offer()会给你一个漂亮而又漂亮的false返回值,而add()会抛出一个你不想在你的代码中使用的令人讨厌的未经检查的exception。 如果添加失败手段代码正在按预期工作,并且/或者您会正常检查,请使用offer() 。 如果添加失败意味着某些内容被破坏,请使用add()并根据Collection接口的规范处理抛出的exception。

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

无论如何,希望澄清至less这部分的问题。

优先级队列有一些优先级分配给每个元素,具有最高优先级的元素出现在队列顶部。 现在,它取决于你如何要分配给每个元素的优先级。 如果你不这样做,Java将以默认的方式进行。 具有最小值的元素被分配最高优先级,因此首先从队列中移除。 如果有几个优先级相同的元素,则任意打断。 您还可以在构造函数 PriorityQueue(initialCapacity, comparator) 使用Comparator指定sorting

示例代码:

 PriorityQueue<String> queue1 = new PriorityQueue<>(); queue1.offer("Oklahoma"); queue1.offer("Indiana"); queue1.offer("Georgia"); queue1.offer("Texas"); System.out.println("Priority queue using Comparable:"); while (queue1.size() > 0) { System.out.print(queue1.remove() + " "); } PriorityQueue<String> queue2 = new PriorityQueue(4, Collections.reverseOrder()); queue2.offer("Oklahoma"); queue2.offer("Indiana"); queue2.offer("Georgia"); queue2.offer("Texas"); System.out.println("\nPriority queue using Comparator:"); while (queue2.size() > 0) { System.out.print(queue2.remove() + " "); } 

输出:

 Priority queue using Comparable: Georgia Indiana Oklahoma Texas Priority queue using Comparator: Texas Oklahoma Indiana Georgia 

否则,您也可以定义自定义比较器:

 import java.util.Comparator; public class StringLengthComparator implements Comparator<String> { @Override public int compare(String x, String y) { //Your Own Logic } } 

以下是您可以用于初始学习的简单示例:

 import java.util.Comparator; import java.util.PriorityQueue; import java.util.Queue; import java.util.Random; public class PQExample { public static void main(String[] args) { //PriorityQueue with Comparator Queue<Customer> cpq = new PriorityQueue<>(7, idComp); addToQueue(cpq); pollFromQueue(cpq); } public static Comparator<Customer> idComp = new Comparator<Customer>(){ @Override public int compare(Customer o1, Customer o2) { return (int) (o1.getId() - o2.getId()); } }; //utility method to add random data to Queue private static void addToQueue(Queue<Customer> cq){ Random rand = new Random(); for(int i=0;i<7;i++){ int id = rand.nextInt(100); cq.add(new Customer(id, "KV"+id)); } } private static void pollFromQueue(Queue<Customer> cq){ while(true){ Customer c = cq.poll(); if(c == null) break; System.out.println("Customer Polled : "+c.getId() + " "+ c.getName()); } } } 

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

请注意,如果sorting是对象的直观sorting,通常最好只使用Comparable而不是Comparator ,例如,如果您有一个按年龄对Person对象进行sorting的用例,则最好使用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