-1

I'm trying to write some code to sort a list of numbers by their absolute difference from a target or, if numbers are equidistant, by the value of the numbers. That is, in pseudocode,

compare( a, b, target ) {
    if ( Math.abs( a - target ) < Math.abs( b - target ) )
        return -1;  // CompareTo convention
    else if ( Math.abs( a - target ) > Math.abs( b - target ) )
        return 1;
    else
        return compare( a, b )

I figured that I could using comparing...thenComparing to do the two-stage comparison, but the thenComparing part seems to cause compilation problems. When I try compiling the following code:

public void fn( int k, int x ) {
    Comparator< Integer > comparator1 =
            Comparator.comparingInt( i -> Math.abs( x - i ) );
    Comparator< Integer > comparator2 =
            Comparator.comparingInt( i -> Math.abs( x - i ) ).
            thenComparingInt( i -> i );
}

I find that the definition of comparator1 is fine but comparator2 gives me the following compilation messages (in Eclipse IDE):

Multiple markers at this line
    - The operator - is undefined for the argument type(s) int, Object
    - Type mismatch: cannot convert from Comparator<Object> to 
      Comparator<Integer>

Can someone please point out what I'm doing wrong?

Mark Lavin
  • 870
  • 1
  • 12
  • 25
  • 1
    Not sure why, probably has to do with boxing, but the type is lost between `comparingInt` and `thenComparingInt` I believe. You need to explicitly indicate the type when calling comparingInt on comparator2. I.e; `Comparator.comparingInt`. If someone more intelligent could expand that would be amazing. – Jason May 24 '22 at 18:51
  • What if you replace `i -> i` with `Function::identity`? – Kayaman May 24 '22 at 18:59

0 Answers0