TreeSet 自動排序:成績升序,成績相同則學號升序。
4. 迭代輸出所有學生資訊。
package com.package1;
import java.util.*;
public class StuScore {
public static void main(String[] args) {
// 1. 定義比較器:成績升序 → 學號升序
Comparator<Student> comparator = (s1, s2) -> {
int gradeDiff = Integer.compare(s1.grade, s2.grade);
if (gradeDiff != 0) return gradeDiff;
return Integer.compare(s1.num, s2.num);
};
// 2. TreeSet 自動去重 + 排序
TreeSet<Student> ts = new TreeSet<>(comparator);
// 3. 生成測試資料
for (int i = 20070301, j = 1; i <= 20070330; i++, j++) {
int grade = 60 + (int)(Math.random() * 41); // 60-100
ts.add(new Student(i, "同學" + j, "男", grade));
}
// 4. 迭代輸出
for (Student s : ts) {
System.out.printf("學號:%d 姓名:%s 性別:%s 成績:%d%n", s.num, s.name, s.sex, s.grade);
}
}
}
// 學生實體類
class Student {
int num; // 學號
int grade; // 成績
String name; // 姓名
String sex; // 性別
public Student(int num, String name, String sex, int grade) {
this.num = num; this.name = name; this.sex = sex; this.grade = grade;
}
}
| 知識點 | 說明 |
|---|---|
| TreeSet 特性 | 基於紅黑樹,元素有序、不重複。依賴 `compare()` 返回 0 判定重複,故比較器必須包含唯一鍵(學號)避免成績相同導致資料丟失。 |
| Comparator 鏈式比較 | 先比成績,再比學號。Java 8+ 推薦 Comparator.comparing(Student::getGrade).thenComparing(Student::getNum) 鏈式寫法。 |
| 隨機數生成 | 60 + (int)(Math.random() * 41) 產生 [60, 100] 整數。 |
| 輸出格式化 | `System.out.printf` 格式化字串,比串聯 `+` 更清晰高效。 |
學號:20070307 姓名:同學7 性別:男 成績:62
學號:20070314 姓名:同學14 性別:男 成績:68
學號:20070324 姓名:同學24 性別:男 成績:68
學號:20070305 姓名:同學5 性別:男 成績:70
...
學號:20070302 姓名:同學2 性別:男 成績:98
成績 68 有兩位同學,按學號 20070314 < 20070324 排序,符合要求。
TreeSet + Comparator 是處理「去重+多鍵排序」的利器。核心在於比較器必須包含唯一業務鍵,確保業務語義上的不重複邏輯與排序邏輯一致。Java 8 Lambda 寫法更簡潔,建議作為首選。