从lambda函数的结果中调用方法

时间:2017-03-28 04:08:11

标签: java lambda

我有一个对象(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

如果给予成年人,有没有办法归还孩子的名字?

2 个答案:

答案 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。