为什么DoubleUnaryOperator带有像
这样的合成的默认实现 DoubleUnaryOperator andThen(DoubleUnaryOperator after);
但是IntToDoubleFunction没有(截至b124,假设功能已完成)。有没有特殊原因,IntToDoubleFunction没有
IntToDoubleFunction andThen(DoubleUnaryOperator after);
?
答案 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 for的一个特化 操作数和结果属于同一类型的情况。
因此,根据这一点,只有一个UnaryOperator能够拥有andThen()
,因为参数和结果是相同的类型。对于函数,并不总是可以通过andThen()
链接,因为参数和结果可能不同。