Search code examples
javasortingobjectpriority-queue

Java PriorityQueue with Custom Objects not Sorting Correctly


I don't completely understand how to use a Java PriorityQueue (max Heap) for custom objects.

I'm working on a LeetCode problem where my code must reorder the words in a sentence by word length. My instinct was that I could use a PriorityQueue to do the work of word-ordering for me. To do that, I thought I could track words with a custom object:

public class word implements Comparable<word>{
    public String theWord;
    public int len, order;
    public word(String w, int order) {
        this.theWord = w;
        this.order = order;
        this.len = w.length();
    }
    @Override
    public int compareTo(word o) {
        return this.len - o.len;                    // sorting behavior controlled here, right???
    }
    public String toString() {
        return this.theWord+"("+this.order+") ";    // for troubleshooting
    }
}

Then:

public String arrangeWords(String sentence) {

    PriorityQueue<word> maxHeap = new PriorityQueue<>(Comparator.naturalOrder());
    String[] words = sentence.split(" ");
    for( int i=0; i<words.length; i++ ) {
        maxHeap.offer( new word(words[i], i) );
    }
}

The first sentence I'm using to test is "leetcode is cool". (From the LC post.)

The ordering I'm hoping for is: "is cool leetcode" (shortest-to-longest word order)

But when I run the above code and check the PriorityQueue in the debugger, I see:

is(1)  leetcode(0)  cool(2)

Sooo... what the heck? I don't understand how this is ordered at all. This is not the original order (indicated by parenthesis), not in length order, not even in alphabetical order. I have no idea how the PriorityQueue is deciding how to order the word objects. I thought that the class word's compareTo() method would force the ordering that I want. (I've seen this with other SO posts.) But not so. Does someone see what I'm going wrong? Thank you.


Solution

  • You inserted them in priority queue. But then you need to poll the queue to get the right order of words.

            while (!maxHeap.isEmpty()) {
                System.out.println(maxHeap.poll());
            }
    

    Also please note the order field won't get altered just because you inserted them in priority queue. It just shows the order in which the word appears in original sentence.

    Write that loop after your for loop where you inserted. Then execute again. You will see right order.