では「同点処理を含めた汎用ランキングユーティリティ」を作ってみましょう。これで、どんな型のリストでも Comparator を渡せば 同点は同順位でランキング表示できるようになります。
汎用ユーティリティクラス
import java.util.*;
import java.util.stream.*;
public class RankingUtils {
/**
* 同点処理を含めたランキング表示ユーティリティ
* @param list ソート対象リスト
* @param comparator ソート条件
* @param topN 上位N件だけ表示(N <= 0 の場合は全件表示)
* @param scoreExtractor スコア抽出関数(例: e -> e.getScore())
* @param formatter 表示フォーマッタ(例: e -> e.getName() + "(" + e.getScore() + ")")
*/
public static <T> void printRankingWithTie(List<T> list,
Comparator<? super T> comparator,
int topN,
java.util.function.ToIntFunction<T> scoreExtractor,
java.util.function.Function<T, String> formatter) {
List<T> sorted = list.stream()
.sorted(comparator)
.collect(Collectors.toList());
int limit = (topN > 0) ? Math.min(topN, sorted.size()) : sorted.size();
int rank = 1; // 現在の順位
int prevScore = Integer.MIN_VALUE; // 前のスコア
int displayRank = 1; // 表示する順位(同点なら同じ)
for (int i = 0; i < limit; i++) {
T item = sorted.get(i);
int score = scoreExtractor.applyAsInt(item);
if (score != prevScore) {
displayRank = rank;
}
System.out.println(displayRank + "位: " + formatter.apply(item));
prevScore = score;
rank++;
}
}
}
Java利用例(Employeeクラス)
class Employee {
private String name;
private int score;
public Employee(String name, int score) {
this.name = name;
this.score = score;
}
public String getName() { return name; }
public int getScore() { return score; }
}
Javaメインクラス
import java.util.*;
public class Main {
public static void main(String[] args) {
List<Employee> employees = Arrays.asList(
new Employee("Tanaka", 90),
new Employee("Sato", 85),
new Employee("Suzuki", 90),
new Employee("Kato", 70),
new Employee("Ando", 85)
);
System.out.println("=== 社員ランキング(同点は同順位・トップ5) ===");
RankingUtils.printRankingWithTie(
employees,
Comparator.comparingInt(Employee::getScore).reversed().thenComparing(Employee::getName),
5,
Employee::getScore,
e -> e.getName() + " (" + e.getScore() + ")"
);
}
}
Java実行例
=== 社員ランキング(同点は同順位・トップ5) ===
1位: Suzuki (90)
1位: Tanaka (90)
3位: Ando (85)
3位: Sato (85)
5位: Kato (70)
実務メリット
- 同点処理対応: スポーツ大会や成績表などで必須。
- 汎用性: Comparator とスコア抽出関数を渡せばどんな型でも利用可能。
- 再利用性: 共通ユーティリティとしてプロジェクト全体で使える。
- 柔軟性: トップNだけ表示、全件表示、フォーマット変更も簡単。
