This is related to this question: How to do function composition?
I noticed that a method reference can be assigned to a variable declared as Function
, and so I assume it should have andThen
or compose
function, and hence I expect that we can compose them directly. But apparently we need to assign them to a variable declared as Function
first (or type-cast before invocation) before we can call andThen
or compose
on them.
I suspect I might have some misconception about how this should work.
So my questions:
andThen
method?Sample code below.
public class MyMethods{ public static Integer triple(Integer a){return 3*a;} public static Integer quadruple(Integer a){return 4*a;} public int operate(int num, Function<Integer, Integer> f){ return f.apply(num); } public static void main(String[] args){ MyMethods methods = new MyMethods(); int three = methods.operate(1, MyMethods::triple); // This is fine // Error below // int twelve = methods.operate(1, (MyMethods::triple).andThen(MyMethods::quadruple)); // But this one is fine Function<Integer, Integer> triple = MyMethods::triple; Function<Integer, Integer> quadruple = MyMethods::quadruple; int twelve = methods.operate(1, triple.andThen(quadruple)); // This one is also fine int twelve2 = methods.operate(1, ((Function<Integer, Integer>)MyMethods::triple).andThen(MyMethods::quadruple)); } }
In Eclipse it's highlighted with the error message:
The target type of this expression must be a functional interface
and in Java 8 compiler the error is:
java8test.java:14: error: method reference not expected here int twelve = methods.operate(1, (MyMethods::triple).andThen(MyMethods::quadruple)); ^ 1 error
(actually, why is the error in Eclipse different from the one from Java 8 compiler?)
Method references are a special type of lambda expressions. They're often used to create simple lambda expressions by referencing existing methods. There are four kinds of method references: Static methods. Instance methods of particular objects.
To make the code clear and compact, In the above example, one can turn lambda expression into a method reference: list. forEach(System. out::println);
A method reference is an alternative to creating an instance of a reference type. Among several other uses, method references can be used to create a functional interface instance (that is, an instance of a functional interface type).
A method reference is similar to lambda expression used to refer a method without invoking it while constructor reference used to refer to the constructor without instantiating the named class. A method reference requires a target type similar to lambda expressions.
As Brian Goetz (project lead for Java lambdas) says, "Lambda expressions have no intrinsic type" (which applies to method references too). This is why you need to cast (or assign) to type Function
before its methods become available.
The reason Eclipse shows different error messages from the JDK compiler (javac) is that Eclipse uses its own Java compiler, called ecj, which is a totally different program from javac. This is, BTW, why Eclipse can run on the JRE, without needing a full JDK install.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With