怎么做功能组合?

Yur*_*nyy 33 java java-8

虽然不耐烦地等待Java 8发布,在阅读Brian Goetz的精彩"Lambda状态"文章之后,我注意到功能组合根本没有被覆盖.

根据上面的文章,在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;
Run Code Online (Sandbox Code Playgroud)

现在,如果我想将这两个函数组合成一个函数映射Person到country,我怎样才能在Java 8中实现这一点?

And*_*hev 52

有一个默认的接口函数Function::andThenFunction::compose:

Function<Person, String> toCountry = personToAddress.andThen(addressToCountry);
Run Code Online (Sandbox Code Playgroud)

  • 就在昨天,我试图得到几乎完全相同的东西,但我有一个`IntFunction` ---它只有`apply`.我想知道为什么... (5认同)

Mik*_*sov 17

使用compose和存在一个缺陷andThen.你必须有显式变量,所以你不能使用这样的方法引用:

(Person::getAddress).andThen(Address::getCountry)
Run Code Online (Sandbox Code Playgroud)

它不会被编译.太遗憾了!

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

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)
Run Code Online (Sandbox Code Playgroud)

  • @Yura,伙计们,`函数<Person,String> fn = p - > p.getAddress().getCountry();`?它比使用这个发明的'compose`甚至不工作`(Person :: getAddress).然后(Address :: getCountry)更短 (6认同)
  • 好点 - 真的很遗憾它不能这样工作:)但是可以通过在第一个方法引用上使用显式强制转换来调用`andThen`方法:`((Function <Person,Address>)Person :: getAddress) .andThen(地址:getCountry)` - 看起来仍然很难看,但它已经是一个单行.还请注意第二种方法的类型引用它会自动扣除,因此不需要显式转换 (4认同)
  • @TagirValeev是的 - 你是对的,这是提到问题的另一个简单的解决方案:)但对我来说,从功能编程的角度来看,`andThen`和`compose`更有趣 (2认同)
  • 这个答案中的“compose”使用与传统相反的函数应用顺序:https://en.wikipedia.org/wiki/Function_composition (2认同)