【问题标题】:How to do function composition?函数组合怎么做?
【发布时间】:2013-11-07 11:20:45
【问题描述】:

在相当不耐烦地等待 Java 8 发布时,在阅读了精彩的 'State of the Lambda' article from Brian Goetz 之后,我注意到 function composition 根本没有被覆盖。

根据上述文章,在 Java 8 中应该可以实现以下功能:

// having classes Address and Person
public class Address {

    private String country;

    public String getCountry() {
        return country;
    }
}

public class Person {

    private Address address;

    public Address getAddress() {
        return address;
    }
}

// we should be able to reference their methods like
Function<Person, Address> personToAddress = Person::getAddress;
Function<Address, String> addressToCountry = Address::getCountry;

现在,如果我想将这两个函数组合成一个将Person 映射到国家/地区的函数,我该如何在 Java 8 中实现这一点?

【问题讨论】:

    标签: java java-8


    【解决方案1】:

    default接口函数Function::andThenFunction::compose

    Function<Person, String> toCountry = personToAddress.andThen(addressToCountry);
    

    【讨论】:

    • 是的,这确实是我感兴趣的,因此接受你的回答:)
    • 就在昨天,我试图得到几乎完全相同的结果,但我有一个IntFunction---它除了apply之外什么都没有。我想知道为什么...
    【解决方案2】:

    使用composeandThen 存在一个缺陷。你必须有明确的变量,所以你不能使用这样的方法引用:

    (Person::getAddress).andThen(Address::getCountry)
    

    它不会被编译。太可惜了!

    但是你可以定义一个实用函数并愉快地使用它:

    public static <A, B, C> Function<A, C> compose(Function<A, B> f1, Function<B, C> f2) {
            return f1.andThen(f2);
        }
    
    compose(Person::getAddress, Address::getCountry)
    

    【讨论】:

    • 好点 - 很遗憾它不能以这种方式工作 :) 但是可以通过在第一个方法引用上使用显式强制转换来调用 andThen 方法:((Function&lt;Person, Address&gt;) Person::getAddress).andThen(Address:getCountry) - 仍然看起来很难看,但它已经是单行了。另请注意,第二种方法引用的类型会自动扣除,因此无需显式转换
    • @Yura,伙计们,Function&lt;Person, String&gt; fn = p -&gt; p.getAddress().getCountry(); 有什么问题?它比使用这个发明的compose 更短,甚至不工作(Person::getAddress).andThen(Address::getCountry)
    • @TagirValeev 是的 - 你说得对,这是解决上述问题的另一个简单方法 :) 但是对我来说,从函数式编程的角度来看,andThencompose 更有趣
    • compose 在这个答案中使用了与传统相反的函数应用顺序:en.wikipedia.org/wiki/Function_composition
    猜你喜欢
    • 1970-01-01
    • 2014-06-16
    • 2017-11-22
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    • 2014-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多