導入
Javaでコレクションを扱う際、特定の条件でデータを並び替えることは避けて通れない作業です。しかし、複数の条件を組み合わせたり、昇順・降順を切り替えたりする際、if文を羅列していませんか?Java 8以降のComparatorインターフェースを使いこなせば、驚くほど簡潔で読みやすいコードが実現できます。今回は、実務で必須のComparatorメソッド群と、あわせて覚えておきたい比較演算のテクニックを解説します。
基礎知識
Comparatorは、オブジェクト同士の「順序」を定義するためのインターフェースです。かつてはcompareメソッドを匿名クラスで実装していましたが、Java 8の関数型インターフェース化により、ラムダ式やメソッド参照で非常にスマートに記述できるようになりました。
reversed()は、既存の順序を反転させるメソッドです。
thenComparing()は、第一条件が同値だった場合に、第二条件で比較を行うためのメソッドです。これらを使うことで、多段的なソートが数行で書けます。
実装とサンプルプログラム
以下のコードは、従業員リストを「部署の昇順」で並べ、部署が同じ場合は「給与の降順」で並び替える例です。
サンプルコード
import java.util.;
public class SortExample {
record Employee(String name, String dept, int salary) {}
public static void main(String[] args) {
List list = Arrays.asList(
new Employee("佐藤", "営業", 300),
new Employee("鈴木", "開発", 500),
new Employee("田中", "営業", 400)
);
// 1. 部署(昇順) -> 給与(降順) でソート
// Comparator.comparingで基準を決め、thenComparingで次条件を追加
list.sort(Comparator.comparing(Employee::dept)
.thenComparing(Comparator.comparingInt(Employee::salary).reversed()));
list.forEach(System.out::println);
}
}
応用・注意点:比較演算とJava 16以降の進化
Comparatorの外でも、比較処理は頻出します。特に注意が必要なのがinstanceofによる型比較です。Java 16から導入された「パターンマッチング」を使うことで、キャストの記述を省略でき、バグを減らせます。
注意点:
1. null対策: Comparator.nullsFirst() や nullsLast() を使うと、nullが含まれるリストでも例外を防いでソートできます。
2. ビット演算: フラグ管理などでビット演算(&, |)を使う場合は、優先順位に注意してください。比較演算子(==, !=)よりもビット演算子の優先順位は低いため、必ず括弧で囲む癖をつけましょう。
3. instanceofの進化:
// 旧来の書き方
if (obj instanceof String) { String s = (String) obj; … }
// パターンマッチングならこう書ける
if (obj instanceof String s) { … sを直接利用可能 … }
実務では、これらを組み合わせることで「読みやすく、かつ堅牢なコード」を目指しましょう。特にComparatorのメソッドチェーンは、複雑なソート条件を宣言的に記述できるため、テストコードの作成も容易になります。ぜひ次回の実装から取り入れてみてください。

コメント