给出了一些Java 8方法函数:
class Foo { Bar getBar() {} }
class Bar { Baz getBaz() {} }
两个访问器的组合看起来像:
Function<Foo, Bar> getBarFromFoo = Foo::getBar;
Function<Bar, Baz> getBazFromBar = Bar::getBaz;
Function<Foo, Baz> getBazFromFoo = getBarFromFoo.andThen(getBazFromBar);
有更简洁的方法吗?这似乎有效
((Function<Foo, Bar>) Foo::getBar).andThen(Bar::getBaz)
但它相当难看。由于优先原因,外围有意义,但为什么演员必要?
(Foo::getBar::getBaz
会很好,但唉......)
让我们定义一个功能界面:
@FunctionalInterface
interface MyFunctionalInterface {
Bar getBar(Foo f);
}
我们可以简化方法参考 Foo::getBar
一点点,
(Foo foo) -> foo.getBar();
意思是 “拿一个 Foo
并返回一个 Bar
“。对于该描述,许多方法都是合适的(例如,我们的接口与 getBar
和a Funtion<Foo, Bar>
用它 apply
):
MyFunctionalInterface f1 = (Foo foo) -> foo.getBar();
Function<Foo, Bar> f2 = (Foo foo) -> foo.getBar();
这就是为什么演员必要的问题的答案。
要回答肯定是否有更简洁的方式的问题,我们必须设定一个背景。上下文明确地给了我们一个 Function
继续合作:
class Functions {
public static <I, O> Function<I, O> of(Function<I, O> function) {
return function;
}
}
Functions.of(Foo::getBar).andThen(Bar::getBaz);
除了Java之外,没有专门用Java编写函数的方法 andThen()
。
你需要执行演员表,因为 Foo::getBar
很暧昧。 **它可以匹配具有类似方法签名的每个接口。
不幸, ((Function<Foo, Bar>) Foo::getBar).andThen(Bar::getBaz)
是你能做的最好的。
也许只是使用lambda表达式?
x -> x.getBar().getBaz()
除了类型模糊之外,没有其他方法可以编写除已经建议的函数之外的函数。这甚至不会比这长得多 Foo::getBar::getBaz
这是你将获得的最好的。如果您认为这样可行:
Foo::getBar::getBaz
它不会。那是因为 Foo::getBar
是一个 多元表达 - 这取决于使用的上下文 - 它可能是一个 Function
,但也可能是一个 Predicate
例如;因此它可能适用于许多事情,所以演员阵容在那里是必要的。
你可以隐藏一个可以进行链接的方法 andThen
,但问题仍然存在。
编辑
在这里查看示例:
public static void cool(Predicate<Integer> predicate) {
}
public static void cool(Function<Integer, String> function) {
}
和表达 cool(i -> "Test");
将无法编译