Java: PriorityQueue returning incorrect ordering from custom comparator? [duplicate]

偶尔善良 提交于 2019-12-29 07:49:08

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!