Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can BiFunction references be passed to methods expecting a functional interface?

I've always only used Java 6 and am right now catching up to learn what's new in Java 8. I was reading this article here: http://www.drdobbs.com/jvm/lambda-expressions-in-java-8/240166764?pgno=2

And it says:

The Java API defines several generic functional interfaces in the java.util.function package. One of the interfaces, BiFunction, describes functions with parameter types T and U and return type R. You can save our string comparison lambda in a variable of that type:

BiFunction<String, String, Integer> comp 
    = (first, second) -> Integer.compare(first.length(), second.length()); 

However, that does not help you with sorting. There is no Arrays.sort method that wants a BiFunction. If you have used a functional programming language before, you may find this curious. But for Java programmers, it's pretty natural. An interface such as Comparator has a specific purpose, not just a method with given parameter and return types. Java 8 retains this flavor. When you want to do something with lambda expressions, you still want to keep the purpose of the expression in mind, and have a specific functional interface for it.

However, when I see this thread: How do you assign a lambda to a variable in Java 8?

The answers to the question there suggest doing exactly what the quoted paragraph says you can't do.

So, is the information in the article incorrect, or am I mis-reading something here?

Thanks!

like image 616
GrowinMan Avatar asked Feb 05 '15 04:02

GrowinMan


1 Answers

I don't see anything in the linked SO answer that contradicts the article.

Regular rules of the type system apply to functional interface.

If you declare a variable as BiFunction<String,String,Integer> bifunc, you will not be allowed to pass it to a method that requires Comparator<String> because BiFunction<String,String,Integer> is not a subtype of Comparator<String>.

The fact that functional types follow all the usual rules is what allowed this new functionality to be added with minimal perturbations.

And if you wish to make a Comparator out of a BiFunction all you have to do is add ::apply like so:

BiFunction<String,String,Integer> bifunc = (a,b) -> 
                               Integer.compare(a.length(), b.length());

Arrays.sort(array, bifunc::apply);  
like image 120
Misha Avatar answered Sep 30 '22 22:09

Misha