java迭代器不能直接修改集合结构,但可通过获取对象引用调用setter安全修改其属性,因不改变modcount,故不会触发concurrentmodificationexception。

Java 迭代器本身不能直接修改对象的属性,但可以通过迭代器获取到集合中的对象引用,再调用该对象的方法(如 setter)来修改其内部状态——这属于“修改对象内容”,而非“修改集合结构”。只要不改变集合大小或顺序(比如 add/remove 元素),这种操作是安全的,不会触发 ConcurrentModificationException。
为什么能安全修改对象属性?
因为:
- 迭代器遍历的是对象的引用,不是副本;
- 修改对象属性(例如
person.setName("Tom"))不改变集合的结构(size、元素位置等); - 集合的
modCount不会变化,迭代器的expectedModCount仍匹配,因此无异常。
常用遍历方式中如何修改对象属性?
增强 for 循环(推荐用于纯属性修改):
代码简洁,适合只读访问或仅需改对象内部字段的场景:
List<person> people = new ArrayList(Arrays.asList(
new Person("Alice", 25),
new Person("Bob", 30)
));
for (Person p : people) {
if ("Alice".equals(p.getName())) {
p.setAge(26); // ✅ 安全:只改对象属性
}
}
// people 中 Alice 的年龄已变为 26
</person>
Iterator 遍历(兼顾属性修改与条件删除):
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
当需要边查边删元素时,用 Iterator 更稳妥;属性修改同样有效:
Iterator<person> it = people.iterator();
while (it.hasNext()) {
Person p = it.next();
if (p.getAge()
<p><strong>ListIterator(支持双向+插入+替换):</strong></p>
<p>若还需在遍历时插入新对象、或用 <code>set()</code> 替换当前元素(注意:是替换整个元素,不是改属性),选它:</p>
<pre class="brush:java;toolbar:false;">ListIterator<person> lit = people.listIterator();
while (lit.hasNext()) {
Person p = lit.next();
if ("Bob".equals(p.getName())) {
p.setAge(31); // ✅ 改属性
lit.set(new Person("Robert", 31)); // ✅ 替换整个元素(非属性)
}
}
</person>
哪些操作要特别注意?
以下行为容易出错,需规避:
- 在增强 for 或普通 for 中调用
list.remove()或list.add()→ 触发 ConcurrentModificationException; - 用
Iterator.set()前未调用过next()或previous()→ 抛 IllegalStateException; - 误以为
iterator.remove()能删掉刚set()的元素 → 实际删除的是上一次next()返回的那个元素。
核心原则:改对象字段没问题,改集合结构要用对应迭代器方法。不需要额外同步,也不依赖外部锁。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










