Javaのreduceの使い方は2種類ある
Javaのreduceの戻り値が異なるのに戸惑っていた。
Javaのreduceの使い方は2種類ある。
ラフなメモ。
【参考】
Java:Streamのreduceの使用方法 | GWT Center
Stream BinaryOperator(Java Platform SE 8 )
Javaのreduceは、Rubyのreduceみたいに、累積する処理みたいなもの。
MapRedcueの間柄のように、map関数とreduce関数はペアで考える。
reduceの引数はBinaryOperator型になるのは分かる。
合計値のように、2つの引数を累積させる処理を行って、1つの戻り値を返すだけ。
しかし、reduce(BinaryOperator)とreduce(初期値, BinaryOperator)は戻り値の型が異なるのに混同していた。
結論は、初期値を設定していなければ、戻り値が空の場合があるのでOptionalでラッピングして返す。
Optionalであれば、NullPointerExceptionのリスクを無くせるメリットがある。
reduceの引数に初期値を設定していれば、戻り値がなくても初期値をそのまま返せばいい。
つまり、戻り値はプリミティブ型でも問題ない。
Java:Streamのreduceの使用方法 | GWT Centerの説明がわかりやすかった。
以下引用している。
【パターン1】Optional
戻り値がない場合があるので、Optionalで返す。
// 何らかの要素があったか
boolean foundAny = false;
// 最終結果
T result = null;
for (T element : このストリームの要素を列挙する) {
if (!foundAny) {
// 最初の要素の場合
foundAny = true;
result = element;
} else {
// 二番目以降の要素の場合
result = accumulator.apply(result, element);
}
}
// 結果があればそれを返す。なければ空を返す
return foundAny ? Optional.of(result) : Optional.empty();
【パターン2】T reduce(T identity, BinaryOperator
初期値が与えられているので「値が存在しない」ということは無く、戻り値はOptionalではない。
// 初期値
T result = identity;
for (T element : このストリームの要素を列挙する) {
// 初期値に加算していく
result = accumulator.apply(result, element);
}
return result;
IntStream (Java SE 11 & JDK 11 )には、reduceの考え方が書かれている。
これは参考になる。
int reduce(int identity, IntBinaryOperator op)
指定された単位元の値と結合的な累積関数を使ってこのストリームの要素に対してリダクションを実行し、リデュースされた値を返します。 これは、次の操作に相当します。
int result = identity;
for (int element : this stream)
result = accumulator.applyAsInt(result, element)
return result;
つまり、reduceは何らかのアルゴリズムに添って累積させる処理を行っている。
その累積処理は抽象化されているので、アルゴリズムにラムダ式を当てはめれば汎用的に使えるわけだ。
| 固定リンク
「Java」カテゴリの記事
- ChatGPTにEclipseでEclEmmaとJaCoCoからカバレッジを出力する方法を聞いた(2023.02.01)
- JavaGold SE11の感想(2022.12.25)
- ComparableとComparatorの違いは何か(2022.11.20)
- Javaのsumはreduceで置き換えられる(2022.11.20)
- JavaのモジュールシステムでSPIとDIを実現するやり方(2022.11.14)
コメント