カテゴリ: Java 更新日: 2025/12/17

Javaのラムダ式でソートする方法まとめ!Collections.sortとStream.sortedの違いと使い分け

【ラムダ式】Collections.sort vs Stream.sorted:使い分けと性能
【ラムダ式】Collections.sort vs Stream.sorted:使い分けと性能

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

生徒

「先生、Javaのリストを並び替えるときってCollections.sortとstream().sorted()のどっちを使えばいいんですか?」

先生

「いい質問だね。それぞれ特徴があって、用途によって使い分けるのがポイントなんだ。」

生徒

「性能とか結果にも違いがあるんですか?」

先生

「あるよ。それじゃあJavaのラムダ式を使ったソート処理について、基本からしっかり見ていこう。」

1. Javaでリストをソートする基本:Collections.sort

1. Javaでリストをソートする基本:Collections.sort
1. Javaでリストをソートする基本:Collections.sort

Javaでリストを昇順や降順に並び替える方法として、昔からよく使われているのがCollections.sort()です。Listを直接並び替える処理であり、リストそのものを変更します(破壊的操作)。

例えば、文字列のリストをアルファベット順にソートしたいときは以下のように書きます。


import java.util.*;

public class SortExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Tanaka", "Yamada", "Sato");
        Collections.sort(names);
        System.out.println(names);
    }
}

[Sato, Tanaka, Yamada]

このように、Collections.sortは破壊的(元のリストを変更)である点に注意が必要です。

2. ラムダ式とComparatorで自由にソート条件を指定

2. ラムダ式とComparatorで自由にソート条件を指定
2. ラムダ式とComparatorで自由にソート条件を指定

Java8以降では、Comparatorにラムダ式を使うことで、より柔軟なソートが可能になります。例えば名前の長さでソートしたい場合、次のように書きます。


Collections.sort(names, (a, b) -> Integer.compare(a.length(), b.length()));

このように、Javaのラムダ式を使えば、比較ロジックを簡潔に記述でき、複雑な条件でも読みやすくなります。

3. Stream.sortedの特徴と非破壊的ソート

3. Stream.sortedの特徴と非破壊的ソート
3. Stream.sortedの特徴と非破壊的ソート

一方、stream().sorted()は、JavaのStream APIのメソッドで、元のリストを変更せず、新しいソート済みのストリームを生成するのが特徴です。これを使えば、元のデータを保持したまま、ソートされたデータを取得できます。


List<String> sorted = names.stream()
                            .sorted()
                            .collect(Collectors.toList());

このようにStream.sorted()は非破壊的であり、イミュータブルな処理を意識したコードになります。最近の開発では、再利用性や安全性の面でこちらを好む開発者も多いです。

4. stream().sorted()にラムダ式を使う方法

4. stream().sorted()にラムダ式を使う方法
4. stream().sorted()にラムダ式を使う方法

stream().sorted()も、ラムダ式を使って柔軟にソート条件を指定できます。たとえば、長さでソートする場合は以下のように書きます。


List<String> sorted = names.stream()
                            .sorted((a, b) -> Integer.compare(a.length(), b.length()))
                            .collect(Collectors.toList());

複数条件のソートや、nullチェックなどもラムダ式と組み合わせて使うと、非常に強力です。

5. Collections.sortとStream.sortedの違いを表で比較

5. Collections.sortとStream.sortedの違いを表で比較
5. Collections.sortとStream.sortedの違いを表で比較

以下は、それぞれの使い方の違いをわかりやすくまとめた比較表です。

項目 Collections.sort Stream.sorted
Javaバージョン Java5〜 Java8〜
データの扱い 破壊的(元を変更) 非破壊的(元はそのまま)
戻り値 void 新しいリスト
パラダイム 命令型 関数型
可読性 慣れているなら◎ モダンで読みやすい

6. 性能の違いと選び方のポイント

6. 性能の違いと選び方のポイント
6. 性能の違いと選び方のポイント

基本的にソートのアルゴリズムはTimSortで共通しており、性能差は大きくありません。ただし、大量データを扱う場合は、Stream APIによる中間操作の最適化や、並列化(parallelStream)の活用で差が出ることがあります。

並列ソートの例:


List<String> sorted = names.parallelStream()
                            .sorted()
                            .collect(Collectors.toList());

CPUコアが多い環境では、parallelStreamを使うことで高速化が見込めます。ただし、順序が保証されないことがあるため、並び順が重要な処理には注意が必要です。

7. ラムダ式+ソートの実践例(オブジェクト編)

7. ラムダ式+ソートの実践例(オブジェクト編)
7. ラムダ式+ソートの実践例(オブジェクト編)

ユーザー情報などのカスタムオブジェクトを年齢順や名前順で並べる場合も、ラムダ式とComparatorを組み合わせることで柔軟なソートが可能です。


class User {
    String name;
    int age;
    User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

List<User> users = Arrays.asList(
    new User("Tanaka", 30),
    new User("Yamada", 25),
    new User("Sato", 35)
);

List<User> sorted = users.stream()
                          .sorted((a, b) -> Integer.compare(a.age, b.age))
                          .collect(Collectors.toList());

このように、ラムダ式を使ったソート処理は、ビジネスロジックでも多用されており、Javaのラムダ式とStream APIのソートを組み合わせることで、より効率的なコーディングが可能になります。

8. 結局どっちを使えばいいの?初心者向けの選び方

8. 結局どっちを使えばいいの?初心者向けの選び方
8. 結局どっちを使えばいいの?初心者向けの選び方

もしあなたがJavaに慣れておらず、既存コードがCollections.sortを使っているなら、最初はそのまま使っても問題ありません。しかし、今から新しくコードを書くなら、以下のポイントで判断しましょう。

  • 元のリストを書き換えたい → Collections.sort
  • 元データを変更したくない → stream().sorted()
  • 並列処理したい → parallelStream().sorted()
  • 読みやすく書きたい → ラムダ式+Stream

Javaのラムダ式とStream APIをマスターすると、可読性が高く、安全性の高いコードを書くことができます。Javaのソート処理をもっとスッキリ書きたい方は、ぜひstream().sorted()を使ってみてください。

まとめ

まとめ
まとめ

Javaのラムダ式を使ったソート処理の全体像を振り返る

この記事では、Javaにおけるソート処理をテーマに、Collections.sortとStream.sortedの違い、そしてラムダ式やComparatorを使った柔軟な並び替え方法について詳しく学びました。Javaでリストやオブジェクトをソートする処理は、業務システムや学習用プログラムのどちらでも頻繁に登場する重要な知識です。

従来から使われてきたCollections.sortは、リストそのものを並び替える破壊的なソートであり、シンプルで分かりやすい反面、元のデータを保持したい場合には注意が必要でした。一方で、Java8以降に登場したStream APIのsortedメソッドは、元のリストを変更せずに新しいソート結果を生成するため、安全性や再利用性の面で優れています。

ラムダ式とComparatorによる柔軟な条件指定

ラムダ式を使うことで、ソート条件を非常に簡潔に記述できる点も大きなポイントです。文字列の長さで並び替えたり、数値の大小で比較したりといった処理を、匿名クラスを使わずに書けるため、コード全体の可読性が向上します。Javaのラムダ式は、ソート処理との相性が非常によく、現代的なJavaプログラミングには欠かせない要素と言えるでしょう。

また、オブジェクトのソートにおいても、ラムダ式とComparatorを組み合わせることで、年齢順、名前順、複数条件による並び替えなど、実務で必要とされるさまざまな要件に対応できます。これは、Javaのコレクション操作を理解する上で重要なステップです。

破壊的ソートと非破壊的ソートの使い分け

今回の内容で特に重要なのは、「どちらのソートを使うかは状況次第」という考え方です。元のリストを変更しても問題ない場面ではCollections.sortが有効ですし、データを安全に扱いたい場合や処理の流れを分かりやすくしたい場合にはstream().sorted()が適しています。

さらに、parallelStreamを使えば、大量データを扱う際にパフォーマンス向上が期待できるケースもあります。ただし、並列処理ならではの注意点もあるため、順序が重要な処理では慎重に選択する必要があります。このような判断力も、Javaのソート処理を理解する上で欠かせないポイントです。

まとめとしてのサンプルプログラム

ここで、今回学んだ内容を整理するために、ラムダ式とStreamを使ったソートのサンプルプログラムを改めて確認してみましょう。記事内と同じクラス構成や書き方を意識しています。


List<String> names = Arrays.asList("Tanaka", "Yamada", "Sato");

List<String> sortedNames = names.stream()
                                .sorted((a, b) -> a.compareTo(b))
                                .collect(Collectors.toList());

System.out.println(sortedNames);

このように、stream().sorted()を使うことで、元のリストを変更せずにソート結果を取得できます。ラムダ式による比較処理は直感的で、Java初心者でも理解しやすい構文です。

先生と生徒の振り返り会話

生徒

「Collections.sortとStream.sortedって、結果は同じでも考え方が全然違うんですね。」

先生

「そうだね。元のリストを変更するかどうかは、実務ではとても重要な判断ポイントになるよ。」

生徒

「ラムダ式を使うと、ソート条件がすごく分かりやすく書けるのも印象的でした。」

先生

「その通り。Javaのラムダ式とStream APIを組み合わせることで、読みやすくて安全なコードが書けるようになるんだ。」

生徒

「これからは、元データを残したいときはStream.sortedを選ぶように意識してみます。」

先生

「いい心がけだね。状況に応じて正しいソート方法を選べるようになると、Javaプログラミングの理解が一段深まるよ。」

今回のまとめを通して、Javaのラムダ式によるソート処理、Collections.sortとStream.sortedの違い、そして実践的な使い分けの考え方を整理できたはずです。Javaでのリスト操作やデータ処理をより深く理解するために、ぜひ何度も読み返してみてください。

生成AIを基礎から学びたい方へ

ChatGPTなどの生成AIをこれから学びたい方に向けて、AIスキルアカデミーの口コミ・評判、料金、無料セミナーの内容を詳しくまとめています。

AIスキルアカデミーの口コミ・評判を詳しく見る
カテゴリの一覧へ
新着記事
New1
Java
JavaのassertFalseとは?JUnit5のAssertionsクラスを初心者向けにわかりやすく解説
新規投稿
New2
Thymeleaf
ThymeleafでDBから取得したデータを編集フォームの初期値にセットする方法!Entity連携を初心者向けに解説
新規投稿
New3
Spring
JavaのSpringで使う@FutureOrPresentアノテーションを完全ガイド!初心者でもわかる日付バリデーション
新規投稿
New4
Java
JavaのLocalDateクラスのgetMonthValueメソッド完全ガイド!初心者でもわかる数値で月を取得する方法
新規投稿
人気記事
No.1
Java&Spring記事人気No1
Servlet
JavaサーブレットのdoPostメソッドとは?初心者向けにやさしく解説!
No.2
Java&Spring記事人気No2
Servlet
JavaのHttpServletResponseクラスを初心者向けに徹底解説!
No.3
Java&Spring記事人気No3
Servlet
JavaのHttpServletRequestWrapperとgetSessionメソッドの使い方を徹底解説!初心者向けServletのセッション管理入門
No.4
Java&Spring記事人気No4
Servlet
JavaのServletExceptionクラスを初心者向けに徹底解説!
No.5
Java&Spring記事人気No5
Servlet
JavaのHttpSessionインターフェースとgetSessionContextメソッドを徹底解説!初心者でもわかるセッション管理の基本
No.6
Java&Spring記事人気No6
Java
JavaのStringクラスとlengthメソッドを完全解説!初心者でも理解できる文字列の長さ取得の使い方
No.7
Java&Spring記事人気No7
Servlet
JavaのHttpSessionAttributeListenerとattributeRemovedメソッドの使い方を徹底解説!初心者でもわかるセッション属性の削除と監視
No.8
Java&Spring記事人気No8
Java
Javaのクラスとインスタンス化、コンストラクタの使い方完全ガイド!初心者でもわかるオブジェクト指向の基礎