JavaDeveloper
JavaDeveloper

Reputation: 5660

How to translate following comparator into Comparator.comparing?

My question may be unclear so let me clear it out by example:

Arrays.sort(arr, new Comparator<String>(){
    public int compare(String a, String b){
        return (b + a).compareTo(a + b);
    }
});

I want to use the Comparator.comparing. I tried out the following:

Arrays.sort(arr, Comparator.comparing((a, b) -> (b + a).compareTo((String)a + b)));

I get an error - bad return type in lamdba expression. How to fix this ?

Upvotes: 2

Views: 212

Answers (3)

Nikolas
Nikolas

Reputation: 44456

As already answered, your anonymous class implementation can be shortened into a lambda expression:

Arrays.sort(arr, (a, b) -> (b + a).compareTo(a + b));

If you insist on using Comparator.comparing(), remember it has specific parameters that don't fit your sorting problem.

  • The Comparator.comparing(keyExtractor) returns a specified Comparator for certain key based on the natural way of comparison (Comparator.naturalOrder). Your method doesn't say what is compared, but how it is.
  • The Comparator.comparing(keyExtractor, keyComparator) looks a bit better because you can specify how the specified keys are compared using keyComparator. You can use your logics of comparing and you conclude to:

    Arrays.sort(arr, Comparator.comparing(
        Function.identity(),                  // keyExtractor, WHAT is compared
        (a, b) -> (b + a).compareTo(a + b))); // keyComparator, HOW is it compared
    

    This is a solution using Comparator.comparing that uses a keyExtractor the Function.identity() returning the input back (the same like str -> str lambda expression) since you want still compare the Strings but in a different way specified with a custom Comparator, therefore the only correct way to sort the array as you need is the simplified version omitting the keyExtractor:

    Arrays.sort(arr, (a, b) -> (b + a).compareTo(a + b));
    

    ... which is finally where we started at.

Upvotes: 1

Louis Wasserman
Louis Wasserman

Reputation: 198211

It is impossible to turn that into a call to comparing because it's not a valid Comparator: it doesn't satisfy the Comparator contract, and you should never use it as a Comparator.

To prove it, that Comparator will compare every string as equal to "", but not every string will be equal to each other. That violates the transitivity property.

Upvotes: 4

pero_hero
pero_hero

Reputation: 3194

Comparator.comparing method expects a keyExtractor of type Function. You just need a lambda to implement the Comparator<String> interface here:

Arrays.sort(arr, (a, b) -> (b + a).compareTo(a + b));

Upvotes: 6

Related Questions