我如何得到一个PriorityQueue
排序我希望它排序的东西?
另外,offer
和add
方法之间有区别吗?
使用构造函数重载,它接受Comparator super E> comparator
并传入比较器,该比较器以适当的方式比较排序顺序.如果您举一个如何排序的示例,我们可以提供一些示例代码来实现比较器,如果您不确定的话.(虽然这很简单.)
正如其他地方所说的那样:offer
并且add
只是不同的接口方法实现.在JDK源码中,我有add
电话offer
.虽然add
并且由于能够指示由于大小限制而不能添加该值而通常offer
具有可能不同的行为offer
,但是这种差异是无关紧要的PriorityQueue
.
以下是按字符串长度排序的优先级队列的示例:
// Test.java import java.util.Comparator; import java.util.PriorityQueue; public class Test { public static void main(String[] args) { Comparatorcomparator = new StringLengthComparator(); PriorityQueue queue = new PriorityQueue (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 { @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; } }
这是输出:
短
介质
确实很长
我们可以在Java 8中使用lambda expression
或method reference
引入.如果我们在Priority Queue中存储了一些String值,我们可以提供内联比较器(基于String的长度):
使用lambda表达式
PriorityQueuepq= new PriorityQueue (5,(a,b) -> a.length() - b.length());
使用方法参考
PriorityQueuepq= new PriorityQueue (5, Comparator.comparing(String::length));
然后我们可以使用它们中的任何一个:
public static void main(String[] args) { PriorityQueuepq= new PriorityQueue (5, (a,b) -> a.length() - b.length()); // or pq = new PriorityQueue (5, Comparator.comparing(String::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方法插入一个元素,否则返回false.这与Collection.add方法不同,后者只能通过抛出未经检查的异常来添加元素.offer方法设计用于故障是正常而非异常发生时,例如,在固定容量(或"有界")队列中.
使用容量限制队列时,offer()通常优于add(),只能通过抛出异常来插入元素.而PriorityQueue中是一个基于优先级堆的极大优先级队列.
只需传递Comparator
给构造函数:
PriorityQueue(int initialCapacity, Comparator super E> comparator)
offer
和之间的唯一区别add
是它们所属的界面.offer
属于Queue
,而add
最初在Collection
界面中看到.除此之外,两种方法完全相同 - 将指定的元素插入优先级队列.
来自Queue API:
如果可能,offer方法插入一个元素,否则返回false.这与Collection.add方法不同,后者只能通过抛出未经检查的异常来添加元素.offer方法设计用于故障是正常而非异常发生时,例如,在固定容量(或"有界")队列中.
没有什么不同,如在javadoc中声明:
public boolean add(E e) { return offer(e); }
只是为了回答add()
vs offer()
问题(因为另一个完全回答了imo,这可能不是):
根据接口Queue上的JavaDoc,"offer方法尽可能插入一个元素,否则返回false.这与Collection.add方法不同,Collection.add方法只能通过抛出未经检查的异常来添加元素.refer方法是为当故障是正常而非异常发生时使用,例如,在固定容量(或"有界")队列中."
这意味着如果你可以添加元素(在PriorityQueue中应该总是这样),它们的工作方式完全相同.但是,如果你不能添加元素,offer()
将给你一个漂亮而漂亮的false
返回,同时add()
抛出一个你不想在你的代码中讨厌的未经检查的异常.如果添加失败意味着代码按预期工作和/或它是您正常检查的内容,请使用offer()
.如果添加失败意味着某些内容被破坏,请add()
根据Collection接口的规范使用和处理抛出的结果异常.
它们都实现这种方式来fullfill队列接口来指定在合同offer()
通过返回失败false
(方法在容量限制的队列优选),并且还保持了Collection接口,关于合同指定add()
总是通过抛出异常失败.
无论如何,希望至少澄清问题的那一部分.
在这里,我们可以定义用户定义的比较器:
代码如下:
import java.util.*; import java.util.Collections; import java.util.Comparator; class Checker implements Comparator{ 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 queue=new PriorityQueue (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
offer和add方法之间的区别:link