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

DoubleUnaryOperator andThen(DoubleUnaryOperator after);

IntToDoubleFunction不会(从b124开始,假定功能已完成)。是否有特殊原因导致IntToDoubleFunction没有

IntToDoubleFunction andThen(DoubleUnaryOperator after);

最佳答案

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



没有原始类型的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));

关于java - 为什么IntToDoubleFunction不能与IntToDoubleFunction和Then(DoubleUnaryOperator之后)一起提供,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21612555/

10-10 06:29