Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function interface as function reference

public static void main(String o[]) {
    Map<String, Integer> map = new HashMap<String, Integer>();
    map.put("a", 1);
    map.entrySet().stream().sorted(Comparator.comparing(Entry::getValue)).forEach(System.out::println);
}

Above code builds and runs perfectly but it shouldn't. Comparator.comparing takes a function reference and only those methods which takes one argument and returns one argument can be mapped on this. But in above code getValue is mapped and works fine but it doesn't take any parameter. Code should give build issue but doesn't. Is there any issue with my concept?

like image 781
Umair Zahid Avatar asked Sep 05 '17 10:09

Umair Zahid


1 Answers

The single argument comparing method:

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor)

takes a Function<? super T, ? extends U> argument, which is a functional interface that contains a single method that takes a argument of one type and returns a value of some other type.

Entry::getValue takes an argument of one type (Map.Entry<String, Integer> in your example) and returns a value of some other type (Integer in your example). Therefore it matches the Function functional interface.

But in above code getValue is mapped and works fine but it doesn't take any parameter.

Yes it does - each Map.Entry element taken from the Stream serves as an argument of the apply() method of the Function interface.

Perhaps this will clarify:

Function<Map.Entry<Integer, String>, String> func = Map.Entry::getValue;

The getValue() method of Map.Entry can be viewed as a Function that accepts a Map.Entry instance and return the value of that instance (returned by calling getValue() on that instance).

like image 60
Eran Avatar answered Sep 26 '22 18:09

Eran