我如何让一个PriorityQueue对我想要它排序的东西进行排序?
另外,在提供和添加方法之间有区别吗?
我如何让一个PriorityQueue对我想要它排序的东西进行排序?
另外,在提供和添加方法之间有区别吗?
当前回答
只需将适当的Comparator传递给构造函数:
PriorityQueue(int initialCapacity, Comparator<? super E> comparator)
offer和add之间的唯一区别是它们所属的接口。offer属于Queue<E>接口,而add最初出现在Collection<E>接口。除此之外,这两种方法做的事情完全相同——将指定的元素插入优先级队列。
其他回答
从队列API:
offer方法尽可能插入一个元素,否则返回false。这与合集不同。方法,该方法只能通过抛出未经检查的异常来添加元素。offer方法设计用于故障是正常情况,而不是异常情况,例如在固定容量(或“有界”)队列中。
Java 8解决方案
我们可以使用Java 8中引入的lambda表达式或方法引用。如果我们有一些String值存储在优先队列中(容量为5),我们可以提供内联比较器(基于String的长度):
使用lambda表达式
PriorityQueue<String> pq=
new PriorityQueue<String>(5,(a,b) -> a.length() - b.length());
使用方法参考
PriorityQueue<String> pq=
new PriorityQueue<String>(5, Comparator.comparing(String::length));
然后我们可以使用它们中的任何一个:
public static void main(String[] args) {
PriorityQueue<String> pq=
new PriorityQueue<String>(5, (a,b) -> a.length() - b.length());
// or pq = new PriorityQueue<String>(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
要反转顺序(将其更改为max-priority queue),只需在inline comparator中更改顺序或使用reversed as:
PriorityQueue<String> pq = new PriorityQueue<String>(5,
Comparator.comparing(String::length).reversed());
我们也可以使用Collections.reverseOrder:
PriorityQueue<Integer> pqInt = new PriorityQueue<>(10, Collections.reverseOrder());
PriorityQueue<String> pq = new PriorityQueue<String>(5,
Collections.reverseOrder(Comparator.comparing(String::length))
我们可以看到集合。reverseOrder重载以获取比较器,这对自定义对象很有用。反转函数实际上使用Collections.reverseOrder:
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
Offer () vs add()
根据文件
offer方法尽可能插入一个元素,否则返回 假的。这与合集不同。方法,该方法可能失败 仅通过抛出未经检查的异常来添加元素。报价 方法是为失败是正常使用而设计的,而不是 异常发生,例如在固定容量(或“有界”)中 队列。
在使用有容量限制的队列时,offer()通常比add()更可取,后者只能通过抛出异常而无法插入元素。PriorityQueue是一个基于优先级堆的无界优先级队列。
作为使用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
没有区别,正如在javadoc中声明的那样:
public boolean add(E e) {
return offer(e);
}
只需将适当的Comparator传递给构造函数:
PriorityQueue(int initialCapacity, Comparator<? super E> comparator)
offer和add之间的唯一区别是它们所属的接口。offer属于Queue<E>接口,而add最初出现在Collection<E>接口。除此之外,这两种方法做的事情完全相同——将指定的元素插入优先级队列。