问题
I've written a custom comparator to compare my node classes, but the java priority queue is not returning my items in the correct order.
Here is my comparator:
public int compare(Node n1, Node n2){
if (n1.getF() > n2.getF()){
return +1;
}
else if (n1.getF() < n2.getF()){
return -1;
}
else { // equal
return 0;
}
}
Where getF returns a double. However after inserting several Nodes into the priority queue, I print them out using:
while(open.size() > 0) {
Node t = (Node)(open.remove());
System.out.println(t.getF());
}
Which results in:
6.830951894845301
6.830951894845301
6.0
6.0
5.242640687119285
7.4031242374328485
7.4031242374328485
8.071067811865476
Any ideas why this is so? Is my comparator wrong? Thanks.
Mike
回答1:
How are you printing out those values? I don't think the iterator from PriorityQueue
provides the same ordering assurances that the overall class does, so potentially if you're doing
for(Node n : queue) {
System.out.println(n.getF());
}
You'll be getting unordered output. The ordering assurance only applies to offer
, take
, poll
, peek
, and possibly some other methods.
There's a special mention on the iterator in the javadocs for priority queue http://java.sun.com/javase/6/docs/api/java/util/PriorityQueue.html
回答2:
Don't know what's wrong with your code, but this works for me:
import java.util.*;
public class Test {
public static void main(String[] args) {
PriorityQueue<Node> open = new PriorityQueue<Node>(10,
new Comparator<Node>() {
@Override
public int compare(Node n1, Node n2){
if (n1.getF() > n2.getF()){
return +1;
}
else if (n1.getF() < n2.getF()){
return -1;
}
else { // equal
return 0;
}
}
});
for (int i = 0; i < 20; i++)
open.add(new Node());
while(open.size() > 0) {
Node t = (Node)(open.remove());
System.out.println(t.getF());
}
}
}
class Node {
double d = Math.random() * 10;
public double getF() { return d; }
}
Output:
0.21442281608773262
1.9965384843480016
2.6660026888929824
2.888889937975976
3.098932914222398
3.1059072964534638
4.193212975907516
4.296282412431935
4.3241392173963735
4.825876226139123
5.193550353435191
5.637831708672641
5.949759449054407
6.620639629878806
7.505126870725806
7.966337123623846
8.270840212631589
8.484502118941545
8.730910327480023
9.191324325662219
Make sure getF()
doesn't accidentally return an int-version of the double.
Update: You cannot update the data which defines the order of the elements after insertion. In that case you need to extract the element, updated it, and reinsert it.
来源:https://stackoverflow.com/questions/3048515/java-priorityqueue-returning-incorrect-ordering-from-custom-comparator