Given some Java 8 method functions:
class Foo { Bar getBar() {} }
class Bar { Baz getBaz() {} }
A composition of the two accessors looks like:
Function<Foo, Bar> getBarFromFoo = Foo::getBar;
Function<Bar, Baz> getBazFromBar = Bar::getBaz;
Function<Foo, Baz> getBazFromFoo = getBarFromFoo.andThen(getBazFromBar);
Is there a more concise way? This seems to work
((Function<Foo, Bar>) Foo::getBar).andThen(Bar::getBaz)
But it's rather ugly. The outer parens make sense for precedence reasons, but why is the cast necessary?
(Foo::getBar::getBaz
would be nice, but alas...)
A static method reference refers to a static method in a specific class. Its syntax is className::staticMethodName , where className identifies the class and staticMethodName identifies the static method. An example is Integer::bitCount .
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).
In those cases, it's often clearer to refer to the existing method by name. Method references enable you to do this; they are compact, easy-to-read lambda expressions for methods that already have a name.
Let's define a functional interface:
@FunctionalInterface
interface MyFunctionalInterface {
Bar getBar(Foo f);
}
We can simplify the method reference Foo::getBar
a bit,
(Foo foo) -> foo.getBar();
which means "take a Foo
and return a Bar
". For that description, a lot of methods are suitable (for instance, our interface with the getBar
and a Funtion<Foo, Bar>
with its apply
):
MyFunctionalInterface f1 = (Foo foo) -> foo.getBar();
Function<Foo, Bar> f2 = (Foo foo) -> foo.getBar();
That is the answer to the question why the cast is necessary.
To answer the question whether there is a more concise way affirmatively, we have to set a context. The context unambiguously gives us a Function
to continue working with:
class Functions {
public static <I, O> Function<I, O> of(Function<I, O> function) {
return function;
}
}
Functions.of(Foo::getBar).andThen(Bar::getBaz);
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