Effective Java Item 58:優先使用 for-each 迴圈而非傳統 for 迴圈
整理 Effective Java 書中 Item 58: Prefer for-each loops to traditional for loops 心得筆記
主旨
在 Java 中處理陣列或集合時,for-each 迴圈(也叫 enhanced for loop)比傳統的 for 迴圈更簡潔、更安全、更容易維護。除非遇到特定場景(例如刪除元素、修改值、平行遍歷多集合),否則應優先使用 for-each。
點出問題
傳統 for 寫法看起來沒錯,但潛藏許多風險:
問題在哪?
- 變數(
i,e,a[i])是雜訊,會干擾閱讀理解 - 多處重複使用變數,容易出錯
- 若改變資料結構(例如從陣列改為集合),要改很多地方
for-each 迴圈的優勢
優點總結:
- 語法簡潔,無需 index 或 iterator
- 不易出現 off-by-one 錯誤或 next() 調用錯誤
- 對集合與陣列都適用
- 對巢狀迴圈更友善
巢狀迴圈常見錯誤
以下範例會錯誤地重複呼叫外層迭代器,導致 NoSuchElementException 或邏輯錯誤:
正確做法(但冗長):
最佳做法:使用 for-each
這樣不但簡潔,還避免了複雜的變數錯誤。
哪些情況不適合 for-each?
刪除元素(destructive filtering)
要使用
iterator.remove(),for-each 無法做到可改用 Java 8 的
removeIf:
元素變更(transforming)
若要修改 list 裡的元素值,還是需要用 index:
平行遍歷多集合(parallel iteration)
- 需要同步前進兩個 iterator/index,例如 zip 兩個集合時
Iterable 介面支援 for-each
只要物件有實作 Iterable 介面,就能使用 for-each:
建議:若寫的是「可遍歷元素的類別」,不一定要實作 Collection,但至少該實作 Iterable,方便使用。
小結
for-each 是寫迴圈的推薦方式,有以下優點:
- 可讀性高
- 減少錯誤機率
- 容易維護與 refactor
- 無性能損耗
使用原則:
✅ 能用 for-each 就用 for-each
❌ 除非需要刪除、修改、同步遍歷,不要用傳統 for
乾淨的迴圈邏輯,會讓程式維護起來輕鬆愉快!
Read other posts