Skip to content
Advertisement

How do I map a Comparator to a Comparator using a Function?

I have a comparator of type Comparator<Integer> and a function Function<Pair<Integer,?>,Integer> expressed as Pair::left (that returns an Integer).

I need to obtain a comparator of type Comparator<Pair<Integer,?>>.

If I wanted to simply map a function Function<T,U> to a resulting function Function<T,V> though a function Function<U,V> I could simply apply andThen() method like this:

Function<Integer, String> toBinary = Integer::toBinaryString;
Function<Pair<Integer, ?>, Integer> left = Pair::left;

var pairToBinary = left.andThen(toBinary); // has type Function<Pair<Integer, ?>, String>

Is it possible to obtain Comparator<Pair<Integer,?>> in a similar way?

Advertisement

Answer

If I understood the question correctly, you can use your function pairToBinary as an argument in Comparator.comparing() to obtain a comparator of type Comparator<Pair<Integer,?>>.

record Pair<L, R>(L left, R right) {}
    
Function<Integer, String> toBinary = Integer::toBinaryString;
Function<Pair<Integer, ?>, Integer> left = Pair::left;
var pairToBinary = left.andThen(toBinary); // has type Function<Pair<Integer, ?>, String>
        
Comparator<Pair<Integer, ?>> comparator = Comparator.comparing(pairToBinary);

Alternatively, you can use another flavor of comparing(keyExtractor,keyComparator), in this case you don’t need to declare any of these functions:

Comparator<Pair<Integer, ?>> comparator1 =
    Comparator.comparing(Pair::left,                    // keyExtractor function
        Comparator.comparing(Integer::toBinaryString)); // keyComparator which is capable of comparing objects produced by keyExtractor

I only have Pair::left and a Comparator<Integer>

If you have on your hands a function which produces Integer and Comparator<Integer>, that’s precisely the use-case for comparing(keyExtractor,keyComparator).

You need to provide a function (Pair::left or whatever) as the first argument and a comparator, which can compare objects produced by the function, as the second argument:

Comparator.comparing(Pair::left, myIntComparator)
Advertisement