java - 为什么 IntToDoubleFunction 没有附带 IntToDoubleFunction andThen(DoubleUnaryOperator after)

标签 java java-8 functional-programming

为什么 DoubleUnaryOperator带有组合的默认实现,例如

DoubleUnaryOperator andThen(DoubleUnaryOperator after);

但是IntToDoubleFunction不(从 b124 开始,假定功能完整)。 IntToDoubleFunction 没有一个特殊原因吗

IntToDoubleFunction andThen(DoubleUnaryOperator after);

最佳答案

我刚刚偶然发现了这个问题 - 即许多功能接口(interface)都有一个 andThen方法,但其中许多(即主要是处理原始类型的)没有这样的方法。事实上,我考虑过为这个问题提供悬赏,因为当前的答案并不令人信服:函数可以有一个 andThen方法。事实上,引用类型Function<T, R>接口(interface)确实有一个 andThen方法!但我找到了一个至少对我来说似乎有说服力的理由......


缺少 andThen 没有“明显”的原因原始类型中的方法 ...Function接口(interface)。唯一真正令人信服的技术原因似乎是,由于返回类型和参数类型的特殊化,提供此类方法会强加太多的组合。

考虑引用类型 Function<T, R>界面,其中andThen方法的实现如下:

default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
    Objects.requireNonNull(after);
    return (T t) -> after.apply(apply(t));
}

这允许调用站点的类型推断来解析任意类型组合:

Function<String, Double> f = null;

Function<Double, Long>    g0 = null;
Function<Double, Integer> g1 = null;
Function<Double, Double>  g2 = null;
Function<Double, String>  g3 = null;

Function<String, Long>    c0 = f.andThen(g0); // works
Function<String, Integer> c1 = f.andThen(g1); // works
Function<String, Double>  c2 = f.andThen(g2); // works
Function<String, String>  c3 = f.andThen(g3); // works

类似的组合,例如 ToDoubleFunction ,将如下:

ToDoubleFunction<String> f = null;

DoubleToLongFunction   g0 = null;
DoubleToIntFunction    g1 = null;
DoubleUnaryOperator    g2 = null;
DoubleFunction<String> g3 = null;

ToLongFunction<String>   c0 = f.andThen(g0); 
ToIntFunction<String>    c1 = f.andThen(g1);
ToDoubleFunction<String> c2 = f.andThen(g2);
Function<String, String> c3 = f.andThen(g3);

但这并不能用一个 andThen 来涵盖。方法。这些调用的每个参数和返回类型都是不同的。因此,由于这些类型的特化,这将需要四个 andThen ToDoubleFunction中的方法类:

ToLongFunction<T> andThen(DoubleToLongFunction g) { ... }
ToIntFunction<T> andThen(DoubleToIntFunction g) { ... }
ToDoubleFunction<T> andThen(DoubleUnaryOperator g) { ... }
<V> Function<T, V> andThen(DoubleFunction<? super V> g) { ... }

(对于所有其他原始类型特化来说也是类似的数字)。

引入如此大量的方法会导致 API 不适当的膨胀 - 特别是考虑到 lambda 表示法可以轻松模拟这些情况时:

ToLongFunction<String>   c0 = (t) -> g0.applyAsLong(f.applyAsDouble(t));
ToIntFunction<String>    c1 = (t) -> g1.applyAsInt(f.applyAsDouble(t));
ToDoubleFunction<String> c2 = (t) -> g2.applyAsDouble(f.applyAsDouble(t));
Function<String, String> c3 = (t) -> g3.apply(f.applyAsDouble(t));

关于java - 为什么 IntToDoubleFunction 没有附带 IntToDoubleFunction andThen(DoubleUnaryOperator after),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21612555/

相关文章:

java - 将对象流转换为属性链表

java - 如何通过 lambda 表达式将 Collection<X> 转换为 Object[][]

javascript - 递归使用 Javascript 返回未定义

python - 在Python中使用条件控制变量过滤数组以创建numpy矩阵

scala - 什么是同构和同态

java - 如何在 Resttemplate Spring 中进行操作

java - 如何让maven站点构建到项目模块的正确链接

java - 无法从通知中打开 Activity

java - Cucumber 中的跨浏览器测试

java - 在 Action Bean 中使用 Java 8 ParallelStream 时出现随机 Hibernate 异常