優化都發生在 StudentManager跟Main:
Studnetmanager的優化:
StudentManager 的改動:
1.Lambda + Method Reference(print、sort)
位置:showAll()(students.forEach(System.out::println))
位置:排序方法(Comparator.comparing(Student::getName) 等)
意義:減少樣板碼、提高可讀性。
2.Comparator 常量化(集中管理排序規則)
位置:類別內新增
private static final Comparator<Student> BY_NAME_ASC = ...;
private static final Comparator<Student> BY_NAME_DESC = ...;
private static final Comparator<Student> BY_AGE_ASC_THEN_NAME = ...;
位置:sortByNameAsc/Desc/ByAgeAscThenName() 使用上述
意義:避免重複建立 Comparator、維護更容易。
3.Stream API(平均、搜尋)
位置:averageAge() → mapToInt().average().orElse(0)
位置:searchByAge(int) → stream().filter().collect()
意義:語意直接、避免手動加總與邊界錯誤。
4.removeIf + Objects.equals(刪除安全)
位置:removeByName(String)
return students.removeIf(s -> Objects.equals(s.getName(), name));
位置:removeStudentByindex(int) 加入索引檢查,錯則丟 IndexOutOfBoundsException
意義:避免 for-each 內 remove 造成 ConcurrentModification,並強化邊界處理。
5.Optional 回傳(查詢結果)
位置:findByName(String) → Optional
連動:updateName、updateAgeByName 用 findByName(...).map(...).orElse(false)
意義:呼叫端被迫處理「找不到」;降低 NPE。
檔案 I/O:NIO + UTF-8 + try-with-resources
位置:csaved / loadFromFile / saveToCSV / loadFromCSV / initFile
改用:Files.newBufferedReader/Writer(Paths.get(filename), UTF_8)
意義:跨平台編碼一致、自動關閉資源、程式更穩定。
小補:你若之後把 Manager 泛型化,這些方法也可抽成策略(Codec)注入,但目前不影響這次改動分類。
Main的改動:
1.Enum 管理選單(與排序選項)
位置:新增 enum Menu、enum SortOption,用 from(code) 解析字串
位置:主選單 switch 與排序子選單 switch 改用 Enum
意義:避免 magic number/typo,擴充選單更簡單。
一部分Lambda / switch rule(箭頭 switch)
位置:主選單 switch (menu) { case ADD -> ... }
意義:較傳統 switch 精簡,不需手寫 break。
2.exception(輸入整數)
位置:readIntLine() 用 Integer.parseInt() + NumberFormatException 迴圈重試
意義:避免 InputMismatchException 直接讓程式中止;使用者體驗更好。
3.Shutdown Hook(Exit 時自動存)
位置:main(...) 一開始註冊
Runtime.getRuntime().addShutdownHook(new Thread(() -> manager.saveToCSV(filename)));
位置:離開時用 System.exit(0) 觸發 hook
意義:避免忘記存檔、關視窗也能保存。
FYI::啟動流程(問檔名 → initFile → loadFromCSV)也屬於 Main 的流程責任,不在 Manager。
and that's it for today; gooooonight