Search code examples
javascalaobjectcomparator

How do I write a comparator that compares 2 different fields in a collection of objects?


My compare function below generates an exception Comparison method violates its general contract IllegalArgumentException. Where and what contract is it failing?

def compare(self: A, that: A): Int = {

  val xComp = self.x.compareTo(that.x)
   if (xComp == 0) {
    val yzComp = self.y.compareTo(that.z)
     if ( yzComp <= 0) {
      -1 
    } else {
      1 
    }
  } else {
    xComp
  }
}

Solution

  • It's impossible to make a valid comparator with that constraint, even setting aside that you're not returning 0 when self.y == that.z.

    Most notably, Comparator is required to impose a total order, which in particular means that if compare(a, b) < 0, then compare(b, a) > 0. This is trivially false for your comparator, if a is (0, 1, 0) and b is (0, 0, 1).

    You cannot have a Comparator that compares self.y to that.z that works in general for things like sorting and TreeSet.