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

