简体   繁体   English

Java 中优先级队列中的自定义比较器

[英]Custom Comparator in Priority queue in Java

I am trying to use a priority queue with a custom comparator, However I am not able to achieve my expected functionality.:我正在尝试将优先级队列与自定义比较器一起使用,但是我无法实现预期的功能。:

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;

public class TestMain {

    public static void main(String[] args) {
        Queue<Node> queue = new PriorityQueue<>(new Comparator<Node>() {
            public int compare(Node a, Node b) {
                if(a.level == b.level) {
                    return a.data - b.data;
                }
                return a.level - b.level;
            }
        });
        
        queue.add(new Node(0,1));
        queue.add(new Node(1,2));
        queue.add(new Node(1,4));
        queue.add(new Node(2,3));
        queue.add(new Node(2,7));
        queue.add(new Node(2,2));
        queue.add(new Node(2,5));
        
        System.out.println(queue);
    }
    
    private static class Node {
        int level;
        int data;
        
        Node(int level, int data) {
            this.level = level;
            this.data = data;
        }
        
        public String toString() {
            return level + ":" + data;
        }
    }
}

Expected output = [0:1, 1:2, 1:4, 2:2, 2:3, 2:5, 2:7] Actual output = [0:1, 1:2, 1:4, 2:3, 2:7, 2:2, 2:5]预期 output = [0:1, 1:2, 1:4, 2:2, 2:3, 2:5, 2:7]实际 output = [0:1, 1:2, 1:4, 2:3, 2:7, 2:2, 2:5]

I want the elements in the priority queue to be ordered by the level first then by data.我希望优先级队列中的元素首先按级别排序,然后按数据排序。

Actually the logic is correct, only thing is I am trying to do sysout, then it was showing in the order I have inserted, When I used the remove operation on the priority queue data is coming in expected format.实际上逻辑是正确的,唯一的事情是我正在尝试做 sysout,然后它按照我插入的顺序显示,当我对优先级队列数据使用删除操作时,它以预期的格式出现。

while(!queue.isEmpty()) {
    System.out.println(queue.remove());
}

Output: 0:1 1:2 1:4 2:2 2:3 2:5 2:7 Output: 0:1 1:2 1:4 2:2 2:3 2:5 2:7

The method toString may not display the elements in retrieval order. toString 方法可能不会按检索顺序显示元素。 So, it doesn't mean that your comparator is incorrect.因此,这并不意味着您的比较器不正确。

The following is written in the javadoc for PriorityQueu (emphasis is mine):以下是在PriorityQueu 的 javadoc中编写的(重点是我的):

This class and its iterator implement all of the optional methods of the Collection and Iterator interfaces.这个 class 及其迭代器实现了 Collection 和 Iterator 接口的所有可选方法。 The Iterator provided in method iterator() and the Spliterator provided in method spliterator() are not guaranteed to traverse the elements of the priority queue in any particular order .方法 iterator() 中提供的 Iterator 和方法 spliterator()中提供的 Spliterator 不能保证以任何特定顺序遍历优先级队列的元素 If you need ordered traversal, consider using Arrays.sort(pq.toArray()).如果需要有序遍历,可以考虑使用 Arrays.sort(pq.toArray())。

It isn't written explicitly here, but toString relies on iterators, therefore elements may not be displayed in the expected orther either.这里没有明确写出来,但是 toString 依赖于迭代器,因此元素也可能不会以预期的方式显示。 The toString method is defined in class Collection, and isn't specificly overridden here. toString 方法在 class 集合中定义,此处未具体覆盖。

PriorityQueu is probably implemented using a binary heap in an array. PriorityQueu 可能是使用数组中的二进制堆实现的。 From there, it follows naturally that iteration is made in array order.从那里,很自然地,迭代是按数组顺序进行的。 Displaying elements in the correct order would require removing them from the queue, and is therefore impossible except by sorting a copy somewhere else, what would be too heavy for a simple toString.以正确的顺序显示元素需要将它们从队列中删除,因此除了在其他地方排序副本之外是不可能的,这对于简单的 toString 来说太重了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM