Priority queue ordering of elements
Asked Answered
G

4

13

How come the elements of priority queue are ordered according to natural order by default as it doesn't implement comparable interface?

From the documentation, it says elements are ordered based on natural ordering, but I can't find anywhere it talks about an equals method nor comparable. How is it happening internally?

All Implemented Interfaces: Serializable, Iterable, Collection, Queue.

If it implements comparable, then why doesn't it say in the above line?

Example:

    public static void main(String[] args) {
        PriorityQueue<String> pq = new PriorityQueue<String>();
        pq.add("2");
        pq.add("4");
        System.out.println(pq); //prints [2, 4]
        pq.offer("1");
        System.out.println(pq); // prints [1, 4, 2]
        pq.add("3");
        System.out.println(pq); // prints [1, 3, 2, 4]
    }
}

Also the third print statement prints [1, 3, 2, 4] instead of prints [1, 2, 3, 4]. Why? It should be natural ordering, right?

Greenleaf answered 6/5, 2015 at 8:59 Comment(6)
The sources are in src.zip.Adenovirus
grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/…Sax
@JB Nizet: All Implemented Interfaces: Serializable, Iterable<E>, Collection<E>, Queue<E>Greenleaf
@JBNizet That's all it implements. I can read it says natural ordering but it doesn't implement comparable if you see this: All Implemented Interfaces: Serializable, Iterable<E>, Collection<E>, Queue<E>Greenleaf
E needs to implement Comparable or a Comparator needs to be defined, this is clearly stated in the doc. Why should PriorityQueue implement Comparable?Sax
@JBNizet You may have missed this part of stackoverflow.com/tour "Remember: we're all here to learn, so be friendly and helpful!" Even though your answer is helpful, it could be friendlier.Aragonite
T
22

The actual internal data structure of PriorityQueue is not ordered. It is a heap.

PriorityQueue doesn't need to be ordered. Instead, it focuses on head of data. Insertion is in O(log n) time. Sorting wastes time and is useless for a queue.

Moreover, either the element is-a Comparable, or a Comparator is provided. Unfortunately, non-comparable checking is at runtime, rather than compile time. Once second element is added, ClassCastException occurs.

PLUS: My answer to why [1, 3, 2, 4] instead of prints [1, 2, 3, 4]?

As I mentioned before, it's not ordered. Instead it focuses on head q[0] is minimum; that's it. You could see the [1, 3, 2, 4] as a tree which is not linear:

1
| \
3  2
|
4
Touraine answered 6/5, 2015 at 9:4 Comment(5)
So elements implement comparable or comparator? I didn't get youGreenleaf
@kittu: JavaDoc: A priority queue relying on natural ordering also does not permit insertion of non-comparable objects (doing so may result in ClassCastException).Valaria
wow. thanks a lot. I understood it well with the illustrationGreenleaf
@Greenleaf Hope it helps:) Tree is powerful and interesting data structure.Valaria
If we loop over al the elements we have in an array of size n and then insert them into the priorityQueue, will we have a complexity of n * log n ?Gneiss
B
8

You are seeing that order because:

1. Internally System.out.println() will be invoking the toString() method which in turn uses the iterator to iterate through the elements of the queue. But the iterator does not guarantee any specific order to traverse the elements. Refer this

http://docs.oracle.com/javase/6/docs/api/java/util/PriorityQueue.html


2. Priority queue is based on priority heap. When an element is inserted without any comparator then priority queue uses siftUpComparable() method internally. siftUpComparable() compares the current element with the element at it's parent position in the heap. If the order is not correct then current element and parent element are swapped. This is done until the current element and parent element are in correct order. Ordering is based on natural order of the element.

3. Since priority queue is based on priority heap its main focus will be on element in front of the queue. So the elements are ordered when an element is dequeued from the queue using poll(). This is done to increase the performance of Priority queue. Priority queue only orders the elements when it requires.
If you want to see the order as [1, 2, 3, 4] then use this

while(pq.size() != 0) { 
    System.out.println(pq.poll());
}
Bushel answered 19/7, 2017 at 5:57 Comment(0)
B
1

The priority queue relies on the following to order the elements:

  • Element must be a Comparable type
  • Need to provide Comparator implementation for the queue
Bidden answered 6/5, 2015 at 9:29 Comment(0)
D
0

Actually PriorityQueue allows only those elements which implements Comparable or you need to provide Custom Comparator.

Integer and String values are allowed in Comparator because they implement Comparable interface. e.g. public final class String implements java.io.Serializable, Comparable, CharSequence

public final class Integer extends Number implements Comparable

If you create your own class e.g Employee then it should implement Comparable or you should provide your custom Comparator.

I hope this will resolve your queries!!!!

Detest answered 7/5, 2015 at 10:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.