5

I can't understand the order of PriorityQueue in Java. As i understand they are heap based and they can not provide exact iteration order as insertion order. I want to know then on what basis priorityQueue Sort themselves. Given code:

PriorityQueue<String> pq = new PriorityQueue<String>();
        pq.offer("hepqo");
        pq.offer("bro");
        pq.offer("wassup");
        pq.offer("okay");
        pq.offer("bingo");
        pq.offer("first");
        pq.offer("last");
        pq.offer("ssup");
        System.out.println("polled "+pq.poll());
        System.out.println(pq);
        String str[] = pq.toArray(new String[0]);
        Arrays.sort(str);
        for(String str1:str){
            System.out.println(str1);
        }

produces output:

polledbingo
[bro, hepqo, first, okay, ssup, wassup, last]
bro
first
hepqo
last
okay
ssup
wassup

Even when i convert it to Array, the order is lost.
I can not feel this is even NATURAL ORDERING by String.
Is there any way to maintain the insertion order of priority Queues?
On what basis they sorted on?

user207421
  • 305,947
  • 44
  • 307
  • 483
Sachin Verma
  • 3,712
  • 10
  • 41
  • 74
  • That is, in fact, natural ordering for strings. – Matt Ball Jul 16 '13 at 22:42
  • how come??? its not by comparator, right?? – Sachin Verma Jul 16 '13 at 22:58
  • It's by the `String#compareTo(String)` method. Note that `Queue#poll()` removes an element from the queue, which is why `"bingo"` does not appear in the sorted array output at all. – Matt Ball Jul 16 '13 at 23:01
  • by comparator the output is `[bro, hepqo, first, okay, ssup, wassup, last]` and the expected is: `[bro,first, hepqo, last, okay, ssup, wassup, ]`?? – Sachin Verma Jul 16 '13 at 23:03
  • 2
    **Please** read the JavaDocs: _"The Iterator provided in method `iterator()` is_ not _guaranteed to traverse the elements of the priority queue in any particular order."_ http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html – Matt Ball Jul 16 '13 at 23:05
  • 2
    The only methods in `PriorityQueue` that provide ordering are `poll()` and `peek()`, and you aren't using either of them. It seems to me you want a FIFO queue, not a `PriorityQueue` at all. – user207421 Jul 16 '13 at 23:11
  • iterator do not guarantee order, natural ordering not working, means no way to maintain order???? – Sachin Verma Jul 16 '13 at 23:11
  • @EJP poll() and peek() maintains what order insertion order or natural ordering?? – Sachin Verma Jul 16 '13 at 23:12
  • @EJP got it man thanks!!! but another question: what class/interface provide FIFO queue in java?? – Sachin Verma Jul 16 '13 at 23:14
  • 1
    FIFO queue: `LinkedList` or `ArrayDeque`. – Louis Wasserman Jul 16 '13 at 23:26
  • 1
    `poll()` and `peek()` maintain the ordering according to the class's `Comparable.compareTo()` implementation, or the `Comparator` you provide if any. This is all in the Javadoc. Have you read it? – user207421 Jul 17 '13 at 00:20

2 Answers2

3

The queue is sorting according to the strings' lexicographic order, which is their natural ordering (i.e. 'b' precedes 'f', 'f' precedes 'h', etc). If you want the queue to maintain insertion order, then use a vanilla Queue instead of a PriorityQueue

Zim-Zam O'Pootertoot
  • 17,888
  • 4
  • 41
  • 69
  • in my output, why is `last` is after `wassup`?? – Sachin Verma Jul 16 '13 at 23:00
  • 2
    @Sachin Verma The elements output from [toArray](http://docs.oracle.com/javase/6/docs/api/java/util/PriorityQueue.html#toArray%28%29) are in no particular order - it's only `poll`, `iterator`, etc that are guaranteed to respect the queue's order – Zim-Zam O'Pootertoot Jul 16 '13 at 23:02
  • 4
    @Zim-ZamO'Pootertoot No. See the Javadoc: "The `Iterator` provided in method `iterator()` is not guaranteed to traverse the elements of the priority queue in any particular order." Ordering is only provided via the `peek()` and `poll()` methods. – user207421 Jul 16 '13 at 23:07
  • How do you know this ("The queue is sorting according to the strings' lexicographic order, which is their natural ordering")? any official reference? – FullStackDeveloper Jan 02 '19 at 15:58
-1

The Priority Queues in Java are an implementation of what is called a Heap (which is an abstract data structure). If you look the Heap data structure, there is no strict principle of ordering among the keys (or collection elements in Java terms). Heap ADT is useful for mainly for fast insertion/deletion and O(K) time retrieval of the first element (which will be the root in case of the Heap). So do not use PriorityQueue data structure in Java for searching all elements, sorting elements, or traversing elements. Because it's not meant for those purposes. The javadoc clearly points out that the optional implementations from Collection and Iterable interfaces are not something to rely upon (i.e., Iterator returns an implementation which does not guarantee the order and the Collection methods like remove(), contains() take linear time)

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Sai Dubbaka
  • 621
  • 7
  • 11
  • Of course there's a 'strict principle'. Otherwise it wouldn't work. The 'strict principle' is that `A[i] <= A[i*2] <= A[i*2+1]`. And you can certainly use it for sorting. The `Iterator` methods `hasNext()` and `next()` are not optional. Too much confusion here. – user207421 Oct 19 '17 at 02:27