導入
Javaでリスト内の数値に対して「合計」「平均」「最大値」「最小値」を一度に求めたいとき、皆さんはどうしていますか?それぞれの値を個別にループ処理で計算すると、コードが冗長になり、可読性も低下してしまいます。今回紹介する Collectors.summarizingInt() を使えば、Stream APIを通じてこれらすべての統計情報をわずか1行で、しかも効率的に取得可能です。コードの簡潔さとメンテナンス性を向上させるための必須Tipsです。
基礎知識
Collectors.summarizingInt() は、Java 8から導入されたjava.util.stream.Collectorsクラスの静的メソッドです。このメソッドは、IntStreamやオブジェクトのStreamから整数値を取り出し、その統計情報を保持する IntSummaryStatistics オブジェクトを返します。
このオブジェクトには、count(件数)、sum(合計)、min(最小値)、max(最大値)、average(平均値)といったメソッドが用意されており、一度の集計処理でこれらすべてにアクセスできるのが最大の強みです。
実装/解決策
具体的な流れは以下の通りです。
1. ListやSetなどのコレクションからStreamを生成します。
2. mapToInt() を使い、対象のフィールドをint型に変換します。
3. collect() メソッドの引数に Collectors.summarizingInt() を指定します。
4. 返された IntSummaryStatistics オブジェクトから、必要な統計データを取得します。
サンプルプログラム
以下は、社員リストから「年齢」の統計情報を一括取得する実用的なコード例です。
import java.util.;
import java.util.stream.Collectors;
public class StatisticsExample {
public static void main(String[] args) {
// 社員クラスのリストを想定
List<Employee> employees = Arrays.asList(
new Employee("田中", 25),
new Employee("佐藤", 32),
new Employee("鈴木", 45)
);
// 年齢の統計情報を一括取得
IntSummaryStatistics stats = employees.stream()
.collect(Collectors.summarizingInt(Employee::getAge));
// 結果の表示
System.out.println("人数: " + stats.getCount());
System.out.println("合計年齢: " + stats.getSum());
System.out.println("平均年齢: " + stats.getAverage());
System.out.println("最大年齢: " + stats.getMax());
System.out.println("最小年齢: " + stats.getMin());
}
}
class Employee {
private String name;
private int age;
public Employee(String name, int age) { this.name = name; this.age = age; }
public int getAge() { return age; }
}
応用・注意点
注意点1:空のリストに対する挙動
データが空のリストに対して集計を行った場合、sumは0、countも0になりますが、minやmaxは Integer.MAX_VALUE / MIN_VALUE といったデフォルト値(Integer.MAX_VALUE / MIN_VALUEの状態)を返すため、そのまま利用するとバグの原因になります。必要に応じて、事前にisEmpty()チェックを行いましょう。
応用:LongやDoubleの場合
int型だけでなく、Long型には summarizingLong()、Double型には summarizingDouble() が用意されています。扱いたい数値データの型に合わせてこれらを使い分けることで、精度の高い統計処理が可能です。現場ではログ出力やレポート生成の際に非常に重宝するテクニックですので、ぜひ活用してください。

コメント