Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:PriorityQueue从自定义比较器返回不正确的顺序?_Java_Priority Queue_Comparator - Fatal编程技术网

Java:PriorityQueue从自定义比较器返回不正确的顺序?

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

我已经编写了一个自定义比较器来比较我的节点类,但是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
        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