Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java functional generics [duplicate]

ComputeIfAbsent method of Map has following declaration:

computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction).

Why wasn't parameter declared as Function<K,V> when K and V types are not used anywhere else?

Now I understand that K and V are very important and they are part of the Map class declaration.

like image 792
Mike Avatar asked Jan 30 '23 05:01

Mike


2 Answers

K and V are part of the type of the mapping function. So they are actually used. Specifically, they determine the acceptable and most general bounds for the argument type and the return type of the mapping function.

For

Function<? super K,? extends V> mappingFunction

this means that you can pass any function that is able to at least map everything that can serve as a key in your map (thus ? super K) and maps those keys to values that can be put into the map (thus extends V). In effect this gives you more flexibility in the choice of the mapping function.

In more theoretical terms: under sub-typing functions are contravariant in its argument type and covariant in its return type. This determines the type of mappingFunction to Function<? super K,? extends V> when regarding Map<K, V> as a function from K to V.

like image 191
michid Avatar answered Feb 02 '23 10:02

michid


Simple example:

Map<String,Object> myMap = ...
Function<Object,String> myFunc = Object::toString;
myMap.computeIfAbsent("42", myFunc);

Is this acceptable?

Well, given the type of myFunc is Function<Object,String>, and we have a Map<String,Object>, which sounds like there is a problem. It certainly wouldn't compile if you only accepted Function<K,V>.

But when you look at it closer, there isn't anything wrong. Not only does the code demonstrably work, it's also easy to see why it works: "42" is an instance of String, which has a toString() method. That method returns a String, which is of course an Object. So of course it's fine.

And this "fine"-ness is what is expressed by Function<? super K, ? extends V>.

like image 45
2 revs Avatar answered Feb 02 '23 10:02

2 revs