增强 for 循环不能修改集合元素值;因其本质是迭代器遍历,局部变量赋值仅改变副本或引用变量本身,不影响原集合,需用传统 for 循环配合索引或 listiterator 才能修改。

增强 for 循环不能修改集合元素值?
不能直接改。Java 的 for-each 本质是用迭代器遍历,拿到的是元素的副本(对基本类型)或引用(对对象),但修改局部变量不会反向作用到原集合里。
常见错误现象:for (String s : list) { s = s.toUpperCase(); } 执行完 list 里的字符串没变——因为 s 是新变量,赋值只改了它自己。
- 真要改集合内容,得用传统
for循环配索引:for (int i = 0; i - 对象字段可改:如果
list存的是自定义对象,for (Person p : list) { p.setName(p.getName().toUpperCase()); }是有效的,因为p和原集合中引用的是同一个对象 - 别在循环里调
add()或remove(),会触发ConcurrentModificationException
哪些容器支持 for-each?
只要实现了 Iterable 接口就能用,包括 ArrayList、LinkedList、HashSet、HashMap.values()、数组(语法糖支持)等。
不支持的典型场景:Iterator 本身、Enumeration、没实现 Iterable 的老式容器(如 Stack 虽继承 Vector,但能用;真正不行的是像早期自定义类没加接口)。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 数组可以:
int[] arr = {1,2,3}; for (int x : arr) {...}—— 这是 JVM 层级支持,不是靠Iterable -
HashMap不能直接for (Entry e : map),必须写成for (Entry e : map.entrySet()) - 性能上,对
ArrayList,for-each和传统for差不多;但对LinkedList,for-each内部用迭代器,比用索引的get(i)快得多(后者是 O(n) 遍历)
空指针或并发修改异常怎么快速定位?
NullPointerException 常发生在集合本身为 null:for (String s : list) 中 list == null 就崩;ConcurrentModificationException 则多见于边遍历边改结构(比如删元素)。
- 安全写法:遍历时修改集合,用
Iterator.remove(),例如Iterator<string> it = list.iterator(); while (it.hasNext()) { if (it.next().isEmpty()) it.remove(); }</string> - 检查空:写成
if (list != null) for (String s : list) {...},或者用Objects.requireNonNull(list)提前报错 - 注意隐式修改:某些集合包装类(如
Collections.unmodifiableList())在for-each中看似正常,但若内部尝试修改会抛UnsupportedOperationException
for-each 和传统 for 性能差多少?
多数情况差别微乎其微,JIT 编译后常被优化掉;但有边界情况值得留心。
- 对数组,
for-each会多一次长度读取(每次循环都查array.length),而手动for可提前提取:int len = arr.length; for (int i = 0; i —— 在超大数组+高频循环里可能有几纳秒差异 - 对
Collection,for-each调的是iterator(),传统for若用get(i)对LinkedList是灾难级慢 - 编译后字节码:
for-each展开为标准迭代器模式,没有魔法,只是语法糖
真正容易被忽略的是语义陷阱:以为 for-each 是“更高级”的遍历,就默认它能替代所有场景——其实它连索引都没有,要下标、要双向遍历、要中途 break 后继续操作,还是得切回传统 for 或显式 Iterator。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










