我有一个对象(Adult
)和另一个对象(Child
)作为参数。我正在尝试写一个Function
,如果给予成年人,将返回孩子的姓名。
我写了这个:
public static void main(String[] args) {
Function<Adult, Object> adult_name_f = Adult::getName;
Function<Adult, Object> adult_child_f = Adult::getChild;
Function<Adult, Object> child_name_f = Adult::getChild.getName;
}
static class Adult {
String name;
Child child;
public Child getChild() {
return child;
}
public String getName() {
return name;
}
}
static class Child {
String name;
public String getName() {
return name;
}
}
但(显然)Adult::getChild.getName
不是有效的Function
。
如果给予成年人,有没有办法归还孩子的名字?
答案 0 :(得分:4)
首先,您应指定Function
的适当返回类型。
Function<Adult, String> adult_name_f = Adult::getName;
Function<Adult, Child> adult_child_f = Adult::getChild;
然后,您可以使用Function.andThen()
方法创建第三个Function
。
Function<Adult, String> child_name_f = adult_child_f.andThen(Child::getName);
或者,更常见的是,要创建方法链,您可以使用lambda表达式定义Function
。你甚至可以使用lambda表达式作为前两个,但方法参考更好(生成的代码更少)。
Function<Adult, String> adult_name_f = a -> a.getName();
Function<Adult, Child> adult_child_f = a -> a.getChild();
Function<Adult, String> child_name_f = a -> a.getChild().getName();
测试
Adult mary = new Adult("Mary", new Child("Jesus"));
System.out.println(adult_name_f.apply(mary)); // prints: Mary
System.out.println(adult_child_f.apply(mary)); // prints: Test$Child@XXXXXXXX
System.out.println(child_name_f.apply(mary)); // prints: Jesus
答案 1 :(得分:3)
最简单的方法就是使用lambda。
Function<Adult, Object> child_name_f = adult -> adult.getChild().getName();
请注意,这是Java称为&#34; lambda&#34;的语法。您在问题中使用的语法是方法引用,而不是lambda,但两者密切相关。方法引用始终可以表示为lambda。因此:
Function<Adult, Object> adult_name_f = Adult::getName;
相当于
Function<Adult, Object> adult_name_f = adult -> adult.getName();
[他们的实施方式可能存在差异,但所有实际用途的效果都相同。]
当你想调用两个方法时,使用方法引用语法没有简单的方法,但lambda工作得很好。
有关如何从两个方法引用创建函数组合的其他一些想法,请参阅How to do function composition?。我认为这些答案很有意思,但在现实生活中,我仍然使用lambda。