Java 8 Stream
API の設計を見直して、Stream.reduce()
引数の一般的な不変性に驚きました。
<U> U reduce(U identity,
BiFunction<U,? super T,U> accumulator,
BinaryOperator<U> combiner)
同じ API の一見より用途の広いバージョンは、次のような への個々の参照に共分散/反分散を適用した可能性がありますU
。
<U> U reduce(U identity,
BiFunction<? super U, ? super T, ? extends U> accumulator,
BiFunction<? super U, ? super U, ? extends U> combiner)
これにより、現在不可能な次のことが可能になります。
// Assuming we want to reuse these tools all over the place:
BiFunction<Number, Number, Double> numberAdder =
(t, u) -> t.doubleValue() + u.doubleValue();
// This currently doesn't work, but would work with the suggestion
Stream<Number> stream = Stream.of(1, 2L, 3.0);
double sum = stream.reduce(0.0, numberAdder, numberAdder);
回避策として、メソッド参照を使用して型をターゲット型に「強制」します。
double sum = stream.reduce(0.0, numberAdder::apply, numberAdder::apply);
C# には、次のように定義されているように、宣言サイトの差異を使用して、この特定の問題はありませんFunc(T1, T2, TResult)
。つまり、API を使用するFunc
と、この動作が無料で取得されます。
public delegate TResult Func<in T1, in T2, out TResult>(
T1 arg1,
T2 arg2
)
提案された設計に対する既存の設計の利点 (およびおそらく EG 決定の理由) は何ですか?
または、別の言い方をすれば、私が見落としている可能性のある提案された設計の注意点は何ですか (例: 型推論の難しさ、並列化の制約、または結合性などのリダクション操作に固有の制約、将来の Java の宣言サイトでの差異の予測BiFunction<in T, in U, out R>
、 ...)?