実務では Comparator を無名クラスやラムダで書き捨てるのではなく、専用クラス化してテスト可能にすることがよくあります。これにより、ソートロジックを単体テストで検証でき、保守性も高まります。
実務パターンの流れ
- Comparator を専用クラスとして定義
- ソート条件を明示的にクラスに切り出す。
- 複数条件や複雑なロジックをまとめやすい。
- 利用側では
Collections.sortやList.sortに渡すだけ- 呼び出し側はシンプルになる。
- JUnit などで Comparator 単体テストを作成
- 入力データを用意して、期待通りの順序になるか検証。
サンプルコード
エンティティクラス
class Employee {
private String department;
private int age;
private String name;
public Employee(String department, int age, String name) {
this.department = department;
this.age = age;
this.name = name;
}
public String getDepartment() { return department; }
public int getAge() { return age; }
public String getName() { return name; }
@Override
public String toString() {
return department + " - " + age + " - " + name;
}
}
JavaComparator をクラス化
import java.util.Comparator;
public class EmployeeComparator implements Comparator<Employee> {
@Override
public int compare(Employee e1, Employee e2) {
// 部署 → 年齢 → 名前 の順で比較
int dep = e1.getDepartment().compareTo(e2.getDepartment());
if (dep != 0) return dep;
int age = Integer.compare(e1.getAge(), e2.getAge());
if (age != 0) return age;
return e1.getName().compareTo(e2.getName());
}
}
Java利用側
import java.util.*;
public class Main {
public static void main(String[] args) {
List<Employee> employees = Arrays.asList(
new Employee("Sales", 30, "Tanaka"),
new Employee("HR", 25, "Sato"),
new Employee("Sales", 25, "Suzuki"),
new Employee("HR", 30, "Kato"),
new Employee("Sales", 30, "Ando")
);
employees.sort(new EmployeeComparator());
employees.forEach(System.out::println);
}
}
Javaテスト例(JUnit)
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import java.util.*;
public class EmployeeComparatorTest {
@Test
void testSortByDepartmentAgeName() {
List<Employee> employees = Arrays.asList(
new Employee("Sales", 30, "Tanaka"),
new Employee("HR", 25, "Sato"),
new Employee("Sales", 25, "Suzuki"),
new Employee("HR", 30, "Kato")
);
employees.sort(new EmployeeComparator());
assertEquals("HR", employees.get(0).getDepartment());
assertEquals("Sato", employees.get(0).getName());
assertEquals("Kato", employees.get(1).getName());
assertEquals("Suzuki", employees.get(2).getName());
assertEquals("Tanaka", employees.get(3).getName());
}
}
Java実務でのメリット
- テスト可能性: Comparator のロジックを単体テストで保証できる。
- 再利用性: 複数のサービスや画面で同じソートを使い回せる。
- 可読性: 「このクラスはソートルールを表す」と明示できる。
- 拡張性: 新しい条件を追加するときにクラスを修正すればよい。
💡 まとめ
- Comparator をクラス化すると「ソートルール」を独立した部品として扱える。
- JUnit でテスト可能になり、実務で安心して利用できる。
- 複雑なソート条件(部署→年齢→名前など)を整理しやすい。
