为什么IntToDoubleFunction没有附带IntToDoubleFunction和Then(DoubleUnaryOperator之后)

时间:2014-02-06 19:48:35

标签: java java-8

为什么DoubleUnaryOperator带有像

这样的合成的默认实现

DoubleUnaryOperator andThen(DoubleUnaryOperator after);

但是IntToDoubleFunction没有(截至b124,假设功能已完成)。有没有特殊原因,IntToDoubleFunction没有

IntToDoubleFunction andThen(DoubleUnaryOperator after);

2 个答案:

答案 0 :(得分:1)

我只是偶然发现了这个问题 - 即许多功能接口都有andThen方法这一事实,但其中很多(即主要处理基本类型的方法)做不< / strong>有这样的方法。事实上,我考虑过为这个问题提供赏金,因为目前的答案并不令人信服:函数可以拥有andThen方法。实际上,引用类型Function<T, R>界面 具有andThen方法!但我发现一个至少似乎让我有说服力的原因......

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

考虑引用类型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));

答案 1 :(得分:0)

javadocs似乎区分了Function(IntToDoubleFunction)和UnaryOperator(DoubleUnaryOperator):

Function

  

表示接受一个参数并生成结果的函数。

Unary Operator

  

表示对产生结果的单个操作数的操作   与其操作数相同的类型。这是Function for的一个特化   操作数和结果属于同一类型的情况。

因此,根据这一点,只有一个UnaryOperator能够拥有andThen(),因为参数和结果是相同的类型。对于函数,并不总是可以通过andThen()链接,因为参数和结果可能不同。