Java:PriorityQueue从自定义比较器返回不正确的顺序?
我已经编写了一个自定义比较器来比较我的节点类,但是java优先级队列没有以正确的顺序返回我的项 这是我的比较标准:Java:PriorityQueue从自定义比较器返回不正确的顺序?,java,priority-queue,comparator,Java,Priority Queue,Comparator,我已经编写了一个自定义比较器来比较我的节点类,但是java优先级队列没有以正确的顺序返回我的项 这是我的比较标准: public int compare(Node n1, Node n2){ if (n1.getF() > n2.getF()){ return +1; } else if (n1.getF() < n2.getF()){ return -1; } else { // equal
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;
}
}
其结果是:
6.830951894845301
6.830951894845301
6.0
6.0
5.242640687119285
7.4031242374328485
7.4031242374328485
8.071067811865476
你知道为什么会这样吗?我的比较器错了吗?谢谢
迈克你是如何打印出这些值的?我不认为来自
PriorityQueue
的迭代器提供了与整个类相同的排序保证,因此如果您正在这样做的话,那么可能会这样做
for(Node n : queue) {
System.out.println(n.getF());
}
您将获得无序的输出。订购保证仅适用于报价
、接受
、投票
、偷窥
,以及可能的其他方法
javadocs for priority queue中特别提到了迭代器我不知道您的代码出了什么问题,但这对我很有用:
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; }
}
确保getF()
不会意外返回double的int版本
更新:不能更新定义插入后元素顺序的数据。在这种情况下,您需要提取元素,更新它,然后重新插入它。您的“Java优先级队列”(我假设PriorityQueue)是什么实际的Java类,您是如何构造它的?Java.util.PriorityQueue,我假设?没有回答您的问题,但我注意到您可以将比较器简化为:
返回Double.compare(n1.getF(,n2.getF());
@Gray-我是这样声明的:Comparator Comparator=new NodeComparator();PriorityQueue open=new PriorityQueue(初始大小,Comparator);有点明显,但是,您不在多线程环境中,是吗?在打印数据时没有其他线程写入数据?这是正确的;PriorityQueue
javadoc中的iterator()
方法:“迭代器不会以任何特定顺序返回元素。”“如何打印这些值?”…问题是“我使用…”打印它们。我没有使用迭代器。Comparator Comparator=new NodeComparator();PriorityQueue open=new PriorityQueue(初始大小,Comparator);然后是上面的while循环。你能尝试使用类迭代器吗?看看你是否得到无序的输出?那么它的顺序就不正确了。这是有意义的。如果它实现为堆,它只知道下一个要删除的元素是。嗯……我先将节点添加到prio队列,然后使用节点的“setF”"函数更改后的f值。插入对象后,prio队列中的值是否没有更新?即使我指向prio队列中的节点?@Ceilingfish-我的节点类将f值初始化为-1,然后插入prio队列,然后更新f值。这与上面的不同示例。我感谢您仔细检查基本逻辑,谢谢。PriorityQueue将数据插入正确的位置。在进行轮询之前不会重新调用数据。如果您在插入后更改数据,则不会对其进行排序。Jacob,您可能应该将此注释转换为答案,以便获得信任(这样,看问题的人当然知道在哪里可以找到答案)
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; }
}
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