Home > Net >  Difference between Collections.reverseOrder vs custom comparator
Difference between Collections.reverseOrder vs custom comparator

Time:01-30

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

CodePudding user response:

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().

CodePudding user response:

What I was missing is that returning a 0 in the comparator indicates that the values are equal.

Changing comparator to the following orders things correctly

(a,b) -> a>=b ? -1 : 1
  •  Tags:  
  • Related