Java for-each循環(huán)(遍歷循環(huán))詳解
一、本質(zhì)與語法
// 標準語法 (Java 5+)
for (ElementType element : Iterable/Array) {
// 操作element
}
// 等效傳統(tǒng)實現(xiàn)
Iterator<ElementType> it = collection.iterator();
while (it.hasNext()) {
ElementType element = it.next();
// 操作element
}
設計目標:簡化集合/數(shù)組遍歷,消除顯式迭代器操作
底層機制:
- 對
Iterable對象:自動調(diào)用iterator()獲取迭代器 - 對數(shù)組:轉(zhuǎn)換為傳統(tǒng)索引循環(huán)(編譯后字節(jié)碼可見)
二、核心特性
強制類型安全
List<String> list = Arrays.asList("A", "B");
for (Integer num : list) {} // 編譯錯誤:類型不匹配
不可變性保證
for (final String s : list) {
s = "new"; // 編譯錯誤:final修飾符
}
空指針防護
for (Object obj : null) { ... } // 運行時拋出NullPointerException
三、適用場景與限制
| 支持的數(shù)據(jù)結(jié)構 | 不支持的操作場景 |
|---|---|
| 所有實現(xiàn)Iterable的集合 | 遍歷時刪除元素(需用Iterator.remove()) |
| 數(shù)組 | 需要反向遍歷 |
| 自定義可迭代對象 | 需要同時訪問索引 |
四、典型錯誤案例
并發(fā)修改異常
List<String> list = new ArrayList<>(Arrays.asList("A", "B"));
for (String s : list) {
list.remove(s); // 拋出ConcurrentModificationException
}
? 修正方案:改用迭代器遍歷 + remove()
對象引用陷阱
List<StringBuilder> list = new ArrayList<>();
list.add(new StringBuilder("Hello"));
for (StringBuilder sb : list) {
sb.append(" World"); // 修改對象內(nèi)部狀態(tài) ??
sb = new StringBuilder(); // 僅改變局部引用 ??
}
五、性能對比分析
| 數(shù)據(jù)結(jié)構 | for-each | 傳統(tǒng)for循環(huán) | 推薦方案 |
|---|---|---|---|
| ArrayList | 迭代器遍歷(稍慢) | 索引直接訪問(快) | 大數(shù)據(jù)量選傳統(tǒng)式 |
| LinkedList | 迭代器遍歷(快) | 索引遍歷(O(n²)) | 必須用for-each |
| HashSet | 唯一安全遍歷方式 | 無法直接使用索引 | 強制使用for-each |
六、高級應用技巧
多維數(shù)組遍歷
int[][] matrix = {{1,2}, {3,4}};
for (int[] row : matrix) {
for (int num : row) {
System.out.print(num + " ");
}
}
自定義可迭代對象
class MyIterable implements Iterable<String> {
public Iterator<String> iterator() {
return Arrays.asList("A","B").iterator();
}
}
并行遍歷優(yōu)化(Java 8+)
list.parallelStream().forEach(element -> {
// 多線程處理(注意線程安全)
});
七、最佳實踐指南
優(yōu)先選擇場景
- 只讀遍歷操作
- 無需索引的線性訪問
- 代碼可讀性要求高
規(guī)避風險策略
// 防御性復制(針對可能被修改的集合)
for (String s : new ArrayList<>(originalList)) {
originalList.remove(s); // 安全操作
}
類型推斷優(yōu)化(Java 10+)
var entries = Map.of(1,"A",2,"B").entrySet();
for (var entry : entries) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
深度擴展:Java 14引入的Records類型可與for-each循環(huán)完美配合:
record Point(int x, int y) {}
List<Point> points = List.of(new Point(1,2), new Point(3,4));
for (Point(var x, var y) : points) { // 模式匹配解構(Java 17預覽特性)
System.out.println(x + "," + y);
}
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
簡單了解Thymeleaf語法 數(shù)據(jù)延遲加載使用實例
這篇文章主要介紹了簡單了解Thymeleaf語法 數(shù)據(jù)延遲加載使用實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2010-05-05
SpringBoot集成redis實現(xiàn)共享存儲session
這篇文章主要介紹了SpringBoot集成redis實現(xiàn)共享存儲session的流程步驟,文中通過代碼示例介紹的非常詳細,并總結(jié)了一些常見的錯誤及解決方法,需要的朋友可以參考下2024-03-03
Springboot結(jié)合Mybatis-Plus實現(xiàn)業(yè)務撤銷回滾功能
本文介紹了如何在Springboot結(jié)合Mybatis-Plus實現(xiàn)業(yè)務撤銷回滾功能,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-12-12
Java并發(fā)容器ConcurrentLinkedQueue解析
這篇文章主要介紹了Java并發(fā)容器ConcurrentLinkedQueue解析,2023-12-12
Guava是Google發(fā)布的一個開源庫,主要提供了一些在Java開發(fā)中非常有用的工具類和API,不管是工作還是學習都是非常值得我們?nèi)ナ煜さ模黄饋砜纯窗?/div> 2023-03-03最新評論

