Search code examples
javapriority-queue

adding a specified comparator to java priorityqueue


Im having a hard time understanding how to priorityqueue uses the compareTo method to sort its content.

I have on class called Node. and its has 4 fields.

private char character;
private int frequency;
private Node left_child;
private Node right_child;

Then in my other class called Huffmantree I have a priorityqueue.

My problem:

I want to put object nodes in the queue so that when dequeueing it depends on the (int)frequency of the node.

Now my Node class look like this:

/**
 * Class for creating nodes with a specified character, frequency, 
 *  left- and right child.
 * implements comparable to be able to compare 2 nodes based on their 
 *  frequency.
*/
public class Node implements Comparable<Node>{

    private char character;
    private int frequency;
    private Node left_child;
    private Node right_child;

    public Node(char character, int frequency, Node left_child, Node 
                 right_child){

         this.character = character;
         this.frequency = frequency;
         this.left_child = left_child;
         this.right_child = right_child;
    }
    //Checks if two nodes have equal frequency.
    private boolean equals(Node n){

        return this.frequency == n.frequency;
    }



    @Override
    public int compareTo(Node other) {

        if(this.equals(other)){
            return 0;
        }else if(this.frequency > other.frequency){
            return 1;
        }else return -1;

    }

    //Print out current node
    @Override
    public String toString(){

        return "[" +this.character+"," + this.frequency +"]";

    }

Here I have tried to implement the Comparable interface and I have defined a CompareTo method, comparing Nodes to their frequency value.

In my HuffmanTree class I have tried to make a priorityqueue like this:

PriorityQueue<Node> pq = new PriorityQueue<>(new Comparator<Node>()

but i dont know if this is how u would do it. I´m stuck and I haven't found a good example of this.


Solution

  • Since your Node class already implements the Comparable interface, there is no need to define a Comparator<Node> and pass it to your queue object, just use the no-argument constructor :

    PriorityQueue<Node> pq = new PriorityQueue<>();
    

    According to the official documentation :

    public PriorityQueue() 
    

    Creates a PriorityQueue with the default initial capacity (11) that orders its elements according to their natural ordering.

    In this case, you have defined a natural ordering by implementing the compareTo method for your Node objects, so you're pretty much done. The other constructor which takes a comparator must only be used if the elements in your queue are not Comparables, or you wish to use a different ordering :

    // This queue will hand out nodes in the inverse order of their frequency
    PriorityQueue<Node> queue = new PriorityQueue<>(new Comparator<Node>() {
        @Override
        public int compare(Node a, Node b) {
            return -a.compareTo(b);
        }
    });