我发现我的Java知识在Java 8中已经过时了,我正在努力学习许多新的语言特性。其中之一是函数,特别是compose和andThen方法。
我已经写了一个简单的实验来测试compose和andThen的可逆性
/** Wraps a value
*/
public class Wrap<T> {
private final T value;
private Wrap(T value) {
this.value = value;
}
public static <T> Wrap<T> of(T value) {
return new Wrap<>(value);
}
}
static void functions() {
Function<Integer,String> itos = i->"'"+i+"'";
Function<String,Wrap<String>> stow = s->Wrap.of(s);
Function<Integer,Wrap<String>> itow = itos.andThen(stow);
Function<Integer,Wrap<String>> itow2 = stow.compose(itos);
System.out.println(itow.apply(3));
System.out.println(itow2.apply(3));
}在上面的代码中,不出所料,两个函数itow和itow2似乎是等价的。但它们实际上是等价的吗?在这种情况下,是否在某种程度上偶然地得到了相同的结果?
这种想法认为,compose和andThen方法的存在都是有原因的,函数或BiFunctions可能并不总是以这种方式可逆。你能想到可逆性不适用的情况吗?
发布于 2017-06-02 17:37:13
虽然a.andThen(b)等同于b.compose(a),但在使用方面有实际区别,因为这两个函数中只有一个是已经存在的函数。
假设您有一个已经存在的函数
Function<Integer, String> iToHex = i -> "'" + Integer.toHexString(i) + "'";然后,你想要链接一个字符串转换,例如
Function<Integer, String> itoUpperHex = iToHex.andThen(String::toUpperCase);与andThen相比,显然要方便得多。
Function<Integer,String> itoUpperHex
= ((Function<String,String>)String::toUpperCase).compose(iToHex);另一方面,如果您已经存在的函数是
Function<String, String> quote = s -> "'" + s + "'";并且您想要创建引用的十六进制函数,
Function<Integer, String> iToHex = quote.compose(Integer::toHexString);将会更方便,与
Function<Integer, String> iToHex = ((Function<Integer, String>) Integer::toHexString).andThen(quote);因此,这两种方法中的哪一种取决于已存在的函数。如果这两个函数都已经存在,那么使用哪个方法并不重要(除非您怀疑这些函数中的一个可能已经覆盖了这些方法,以执行更有效的组合)。如果您没有现有的函数作为起点,那么就没有理由使用这些方法中的任何一个,因为您可以将组合表达式编写为单个lambda表达式。
发布于 2017-05-08 21:38:49
它们是等效的。
或者换句话说:x.andThen(y)和y.compose(x)是一样的。
https://stackoverflow.com/questions/43849066
复制相似问题