カテゴリ: Java 更新日: 2026/01/12

JavaのgroupingByを完全ガイド!ラムダ式で集計・グルーピング・重複削除をマスターしよう

【ラムダ式】groupingByの使い方:集計・グルーピング・重複削除
【ラムダ式】groupingByの使い方:集計・グルーピング・重複削除

先生と生徒の会話形式で理解しよう

生徒

「Javaのラムダ式でデータを集計したり、グループ分けしたりする方法ってありますか?」

先生

「はい、ありますよ。Collectors.groupingByを使えば、カテゴリごとに集計したり、特定のキーでグルーピングしたりできます。」

生徒

「具体的にどうやって使うんですか?重複をなくしたりもできますか?」

先生

「もちろんできますよ。それではgroupingByの使い方をわかりやすく説明していきましょう。」

1. groupingByとは?Javaの集計や分類に便利なメソッド

1. groupingByとは?Javaの集計や分類に便利なメソッド
1. groupingByとは?Javaの集計や分類に便利なメソッド

JavaのgroupingByメソッドは、Stream APIと一緒に使ってデータをグループ化するためのメソッドです。特に、ラムダ式を使って条件に応じてリストを分類したいときに便利です。

たとえば、商品のリストをカテゴリ別に分けたい場合や、名前の頭文字でグループに分けたいときに使えます。

2. groupingByの基本的な使い方:カテゴリで分類

2. groupingByの基本的な使い方:カテゴリで分類
2. groupingByの基本的な使い方:カテゴリで分類

まずは基本の使い方を紹介します。ここでは、商品のカテゴリでグループ分けする例を見てみましょう。


import java.util.*;
import java.util.stream.*;
import static java.util.stream.Collectors.*;

public class GroupingExample {
    public static void main(String[] args) {
        List<Product> products = Arrays.asList(
            new Product("りんご", "果物"),
            new Product("バナナ", "果物"),
            new Product("にんじん", "野菜"),
            new Product("トマト", "野菜")
        );

        Map<String, List<Product>> grouped = products.stream()
            .collect(groupingBy(Product::getCategory));

        grouped.forEach((category, list) -> {
            System.out.println(category);
            list.forEach(p -> System.out.println(" - " + p.getName()));
        });
    }
}

class Product {
    private String name;
    private String category;

    public Product(String name, String category) {
        this.name = name;
        this.category = category;
    }
    public String getName() { return name; }
    public String getCategory() { return category; }
}

この例では、getCategory()をキーにして、同じカテゴリのProductがリストにまとめられます。

3. groupingByで集計処理:数をカウントする

3. groupingByで集計処理:数をカウントする
3. groupingByで集計処理:数をカウントする

groupingByは、単にグループ分けするだけでなく、集計処理も同時に行えます。たとえば、各カテゴリに属する商品の数を数えるには次のようにします。


Map<String, Long> counts = products.stream()
    .collect(groupingBy(Product::getCategory, counting()));

このコードでは、各カテゴリに何個の商品があるかをMapにまとめています。

4. groupingByとmappingの組み合わせで必要な情報だけ抽出

4. groupingByとmappingの組み合わせで必要な情報だけ抽出
4. groupingByとmappingの組み合わせで必要な情報だけ抽出

groupingBymappingを組み合わせると、必要なデータだけを抽出してグループにまとめることができます。以下の例では、カテゴリごとに商品名だけをリストにしています。


Map<String, List<String>> groupedNames = products.stream()
    .collect(groupingBy(Product::getCategory, mapping(Product::getName, toList())));

Productオブジェクトのままではなく、getName()で名前だけをリストにしたいときに便利です。

5. groupingByとSetで重複を排除する

5. groupingByとSetで重複を排除する
5. groupingByとSetで重複を排除する

groupingByを使うと、重複のないリストを作ることも可能です。toSet()を使えば、同じ値は自動的に1つにまとめられます。


Map<String, Set<String>> groupedSet = products.stream()
    .collect(groupingBy(Product::getCategory, mapping(Product::getName, toSet())));

重複を除きつつ、カテゴリごとの商品名リストを取得できます。

6. groupingByの中でソートされた順で格納する方法

6. groupingByの中でソートされた順で格納する方法
6. groupingByの中でソートされた順で格納する方法

groupingByはデフォルトでHashMapを使いますが、キーの順番を保持したいときはLinkedHashMapを明示的に指定することで並び順を維持できます。


Map<String, List<Product>> ordered = products.stream()
    .collect(groupingBy(
        Product::getCategory,
        LinkedHashMap::new,
        toList()
    ));

データを順番通りに保持したい場面ではLinkedHashMapを活用しましょう。

7. groupingByを使ってネストされたマップを作る

7. groupingByを使ってネストされたマップを作る
7. groupingByを使ってネストされたマップを作る

groupingByは入れ子構造のグルーピングも可能です。たとえば、カテゴリ→文字数別のグループといった多階層の分類もできます。


Map<String, Map<Integer, List<String>>> nested = products.stream()
    .collect(groupingBy(
        Product::getCategory,
        groupingBy(p -> p.getName().length(), mapping(Product::getName, toList()))
    ));

このように、複雑なグループ分けにもgroupingByは柔軟に対応できます。

8. ラムダ式とgroupingByの相性の良さとは?

8. ラムダ式とgroupingByの相性の良さとは?
8. ラムダ式とgroupingByの相性の良さとは?

Javaのラムダ式は、groupingByとの相性が抜群です。データ加工や分類を直感的に記述できるため、for文よりも簡潔で見やすくなります。特にCollectorsと一緒に使うことで、複雑な集計処理も1行で表現できます。

たとえば、ユーザーの年齢でグループ分けしたり、ログデータを日付単位でまとめたりといった操作もラムダ式でスッキリ書けるようになります。

まとめ

まとめ
まとめ

ここまでJavaのgroupingByについて、グルーピング、集計、重複削除、ネスト構造の分類など、多様な活用方法を具体例とともに丁寧に整理してきました。ラムダ式とStream APIを組み合わせることで、複雑な処理でも直感的かつ簡潔に記述できる点は、実践的な開発において大きな利点となります。特に、カテゴリ別の集計や文字列長による分類、必要な情報だけを抽出するmappingとの組み合わせは、多くの業務アプリケーションでも即戦力として使える場面が多く、汎用性の高いテクニックだといえます。また、重複削除を行いたい場合にはtoSet()を利用し、順序を保持したい状況にはLinkedHashMapを指定することで柔軟に対応できます。これらの機能はデータの分析や可視化などにも応用でき、より効率的な処理を実現します。

さらに、ネストされたマップ構造を扱うことで、階層的なデータ分類にも対応できるようになり、より高度なロジックを組むことが可能です。複数条件を組み合わせた分類を行う場合でも、groupingByを入れ子にして記述するだけで自然に構造化されたデータを得られるため、データ処理における表現力は非常に高くなります。このような柔軟性は、ログ解析や統計処理、商品管理システムなど、さまざまなシーンで応用できる重要な基礎技術です。

また、ラムダ式とgroupingByの相性の良さから、従来のfor文では煩雑になりやすい処理も、短くわかりやすいコードに落とし込むことができ、保守性の向上にもつながります。特に、読みやすさと変更しやすさは現場でも求められるポイントであり、groupingByをしっかりと理解することはJavaプログラミングを一段階上達させる大切なステップといえるでしょう。

サンプルプログラムまとめ

以下はgroupingByの総合的な使い方をまとめたサンプルです。


import java.util.*;
import java.util.stream.*;
import static java.util.stream.Collectors.*;

public class GroupingSummary {
    public static void main(String[] args) {
        List<Product> products = Arrays.asList(
            new Product("りんご", "果物"),
            new Product("バナナ", "果物"),
            new Product("にんじん", "野菜"),
            new Product("トマト", "野菜"),
            new Product("りんご", "果物")
        );

        Map<String, Long> counts = products.stream()
            .collect(groupingBy(Product::getCategory, counting()));

        Map<String, Set<String>> uniqueNames = products.stream()
            .collect(groupingBy(Product::getCategory, mapping(Product::getName, toSet())));

        Map<String, Map<Integer, List<String>>> nested = products.stream()
            .collect(groupingBy(
                Product::getCategory,
                groupingBy(p -> p.getName().length(), mapping(Product::getName, toList()))
            ));

        System.out.println(counts);
        System.out.println(uniqueNames);
        System.out.println(nested);
    }
}

class Product {
    private String name;
    private String category;
    public Product(String name, String category) {
        this.name = name;
        this.category = category;
    }
    public String getName() { return name; }
    public String getCategory() { return category; }
}
先生と生徒の振り返り会話

生徒:「groupingByって、最初は難しそうだと思っていましたが、使い方がわかるととても便利ですね。」

先生:「そうですね。特にラムダ式と組み合わせることで処理がシンプルになりますし、分類や集計の幅が大きく広がります。」

生徒:「mappingを使って必要な情報だけ取り出せるところもすごく役に立ちそうです。」

先生:「はい。実務でも特定の項目だけ抽出したい場面はよくありますし、toSet()で重複削除を行うのも大切なテクニックです。」

生徒:「ネストされたグルーピングができるのも意外でした。分類の幅がさらに広がりますね。」

先生:「その通りです。階層的な分類はデータ分析の基本でもあるので、ぜひ実践でも活用してみてください。」

生徒:「今日の内容をもっと練習して、しっかり身につけたいと思います!」

先生:「ぜひ頑張ってください。groupingByを理解すればJavaのデータ処理がもっと楽しくなりますよ。」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

JavaのgroupingByメソッドとは何ですか?どんな場面で使いますか?

JavaのgroupingByメソッドは、Stream APIと組み合わせてデータを特定の条件でグループ分けするために使います。たとえば商品をカテゴリ別に分類したい場合などに便利です。

Javaの基礎を最初から体系的に学びたい人には、 初心者向けで定評のある定番入門書がこちらです。

スッキリわかるJava入門 第4版をAmazonで見る

※ Amazon広告リンク

カテゴリの一覧へ
新着記事
New1
Spring
SpringDataJPAのJPAクエリメソッド「EndingWith」の使い方を完全ガイド!初心者向け解説
更新記事
New2
Spring
SpringDataJPAのJPAクエリメソッド「StartingWith」の使い方を完全ガイド!初心者向け解説
更新記事
New3
Spring
SpringDataJPAのJPAクエリメソッド「NotLike」の使い方を完全ガイド!初心者向け解説
更新記事
New4
Spring
SpringDataJPAのJPAクエリメソッド「Like」の使い方を完全ガイド!初心者向け解説
更新記事
人気記事
No.1
Java&Spring記事人気No1
Spring
Spring BootとJavaの互換性一覧!3.5/3.4/3.3はJava 21・17に対応してる?
No.2
Java&Spring記事人気No2
Java
JavaのBooleanクラスの使い方を完全ガイド!初心者でもわかる真偽値の操作
No.3
Java&Spring記事人気No3
JSP
JSPの基本タグ一覧と使い方まとめ!実務で使えるタグを紹介
No.4
Java&Spring記事人気No4
Java
JavaのIOExceptionクラス徹底解説!初心者向けファイル入出力エラー対策ガイド
No.5
Java&Spring記事人気No5
JSP
JSPでif文・for文を使う方法!初心者でもわかるJavaとの違いと使い方
No.6
Java&Spring記事人気No6
Spring
SpringのBindingResultを完全ガイド!初心者でもわかる入力チェックとエラー処理
No.7
Java&Spring記事人気No7
Spring
SpringのModelクラスとaddAttributeメソッドの使い方を完全ガイド!初心者でも安心
No.8
Java&Spring記事人気No8
Spring
SpringDataJPAのJPAクエリメソッド「EndingWith」の使い方を完全ガイド!初心者向け解説