I expect the two code snippets to produce the same result, yet they don't. Why? The only difference is the Comparator passed to the PriorityQueue constructor.
import java.util.Collections;
import java.util.PriorityQueue;
public class PriorityQueueTest {
public static void main(String[] args) {
PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
int[] arr = {2,3,9,8,4};
for (int i=0; i<arr.length; i++) {
pq.add(arr[i]);
}
while(pq.size()>0) {
System.out.println(pq.poll());
}
}
}
Output (correct / expected):
9
8
4
3
2
import java.util.Collections;
import java.util.PriorityQueue;
public class PriorityQueueTest {
public static void main(String[] args) {
PriorityQueue<Integer> pq = new PriorityQueue<>((a,b) -> a>b ? 0 : 1);
int[] arr = {2,3,9,8,4};
for (int i=0; i<arr.length; i++) {
pq.add(arr[i]);
}
while(pq.size()>0) {
System.out.println(pq.poll());
}
}
}
Output (wrong / unexpected):
2
9
8
4
3
Comparators must return 3 states: negative, 0 or positive, and must be self consistent such that compare(a,b)
has same sign as -compare(b,a)
when a!=b, and zero if a.equals(b)
.
Your comparator does not satisfy these conditions. You are fortunate your answer works, but if you omit the 0
case in other comparators you may have issues in future.
Instead use:
PriorityQueue<Integer> pq = new PriorityQueue<>((a,b) -> a==b ? 0 : a>b ? -1 : 1);
The above returns the order of elements you expect as for Collections.reverseOrder()
.