1. 導入:なぜCollectors.teeingが重要なのか
JavaのStream APIを使ってリストのデータを集計する際、「合計値と平均値を同時に出したい」「最大値と最小値を一度に取りたい」と思ったことはありませんか?通常、これを行うにはStreamを2回走査するか、複雑なカスタムクラスを作る必要がありました。
Java 12で導入されたCollectors.teeingは、2つの異なる集計処理を並行して行い、最後にそれらの結果を1つにまとめることができる強力なメソッドです。これにより、コードの重複を減らし、パフォーマンスを最適化することが可能になります。
2. 基礎知識:teeingの仕組み
teeingという名前は、ゴルフのティーグラウンド(1つの場所からボールを打ち出すこと)に由来します。
このメソッドは、以下の3つの引数を取ります。
1. 第1のコレクタ:集計処理A
2. 第2のコレクタ:集計処理B
3. マージ関数:AとBの結果を組み合わせて最終的な形にする処理(BiFunction)
Streamの要素をそれぞれのコレクタに「分岐」させて処理し、最後にマージ関数で統合する、というイメージを持つと分かりやすいでしょう。
3. 実装と解決策
例えば、「学生のテスト結果リストから、最高得点と最低得点の差(レンジ)を求めたい」という場合、teeingを使うと非常に簡潔に書けます。
手順としては、Collectors.maxByとCollectors.minByを使い、最後にその2つの値の差を計算する関数を渡すだけです。
4. サンプルプログラム
以下のコードをコピーして、ご自身の環境で試してみてください。
import java.util.;
import java.util.stream.Collectors;
public class TeeingExample {
public static void main(String[] args) {
List
// teeingを使用して最大値と最小値を同時に取得し、その差を計算する
Integer range = scores.stream().collect(Collectors.teeing(
// 1. 最大値を取得するコレクタ
Collectors.maxBy(Integer::compareTo),
// 2. 最小値を取得するコレクタ
Collectors.minBy(Integer::compareTo),
// 3. マージ関数:最大値と最小値を受け取り、差を計算
(max, min) -> max.orElse(0) – min.orElse(0)
));
System.out.println(“最高点と最低点の差は: ” + range);
}
}
5. 応用・注意点:現場での活用
注意点1:可読性とのトレードオフ
teeingは非常に便利ですが、マージ関数の中に複雑なロジックを詰め込みすぎると、コードが読みにくくなります。処理が複雑になる場合は、無理に1行で書こうとせず、メソッドを切り出すことを検討してください。
注意点2:Nullの取り扱い
サンプルコードでも使用している通り、maxByやminByはOptionalを返します。マージ関数内では、orElseなどで値が空だった場合のデフォルト値を指定するのを忘れないようにしましょう。
現場での活用法:
統計情報を一度に算出したい場合(例:件数と合計金額から平均単価を出す等)に、この手法は非常に有効です。Streamを何度も回すとデータ量が大きい場合にパフォーマンスが低下しますが、teeingは1回の走査で済むため、効率的かつモダンなJavaプログラミングを実現できます。

コメント