ArrayList与for循环的故事

本文探讨了从Java的ArrayList中安全删除奇数元素的方法。直接使用for循环结合remove方法会导致逻辑错误,使用Iterator迭代器配合其remove方法可以有效避免并发修改异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**版本1.8

*[0,9]的一个Arraylist,要求把其中奇数删除。

*于是便有了以下代码!

/

import java.util.ArrayList;


public class ArrayTest
{
public static void main(String[] args)
{
ArrayList list = new ArrayList();

for ( int i = 0; i < 10; i++ )
{
list.add( new Integer( i ) );
}

for ( int i = 0; i < list.size(); i++ )
{
int in = (( Integer )list.get( i )).intValue();
if ( in % 2 == 1 )
{
list.remove( i );
}
}

for ( int i = 0; i < list.size(); i++ )
{
System.out.println( list.get(i));
}

}
}

// 输出结果正确



结果分析: ArrayList  list 在执行remove()方法时,list.size()方法返回值会发生改变. 

i == 0 in == 0 if  false

 i==1 in ==1  第一次执行完remove(1)方法后,数据变成0 2 3 4 5 6 7 8 9 list.size() == 9

第二次执行 remove(2)数据变成0 2 4 5 6 7 8 9,list.size() == 8

依次类推....

当执行第5次remove(5)时,数据变成 0 2 4 6 8,list.size() == 5

for判断语句 i == 6 > list.size() == 5;

循环结束。打印结果。。。

因此我觉得这种方法是不科学的,也不安全,因此我采用Iterator迭代器去删除

//下面的代码替代for循环部分

Iterator iter = list.iterator();
while ( iter.hasNext() )
{
Integer in = (Integer)iter.next();
if ( in.intValue() % 2 == 1 )
{
list.remove( in );
}
}

然后问题又来了,抛出异常,


通过查看源代码我们发现

调用list.remove()方法导致modCount和expectedModCount的值不一致。

解决办法:

其实很简单,细心的朋友可能发现在Itr类中也给出了一个remove()方法:

在这个方法中,删除元素实际上调用的就是list.remove()方法,但是它多了一个操作:

expectedModCount = modCount;

因此,在迭代器中如果要删除元素的话,需要调用Itr类的remove方法。

  将上述代码改为下面这样就不会报错了:

Iterator iter = list.iterator();
while ( iter.hasNext() )
{
Integer in = (Integer)iter.next();
if ( in.intValue() % 2 == 1 )
{
iter.remove();
}
}

参考文章:http://www.cnblogs.com/dolphin0520/p/3933551.html

<think>好的,我现在需要帮助用户了解如何使用for循环遍历Java ArrayList,并提供示例代码。首先,我要回顾用户的问题,确保自己理解正确。用户明确提到想用for循环遍历ArrayList,并希望看到示例代码。他们可能已经知道ArrayList的基本概念,但需要具体的代码示例和步骤说明。 接下来,我需要回忆Java中遍历ArrayList的几种常见方法。常见的遍历方式包括基本的for循环、增强型for循环for-each)、迭代器(Iterator)等。但用户特别提到使用for循环,所以重点应放在基本for循环和增强型for循环上。 然后,我应该考虑如何组织回答结构。用户希望结构清晰,逐步解决问题,所以分步骤说明比较合适。例如,先介绍基本for循环,然后增强型for循环,可能再提到注意事项,比如遍历时删除元素的问题,但用户的问题主要是遍历,所以可能需要简要提及,但重点在遍历方法。 接下来要检查是否有相关的引用内容需要引用。用户提供的引用中有引用[1]提到使用for循环遍历List的示例,引用[3]提到遍历时删除元素的正确方法。虽然用户的问题主要是遍历,但可能在注意事项部分引用到这些内容,特别是引用[1]中的示例代码。需要确保正确标注引用来源,比如在示例代码部分引用[^1]。 然后,我需要确保示例代码的正确性。基本for循环使用size()和get()方法,而增强型for循环直接迭代元素。例如: 基本for循环for (int i = 0; i < list.size(); i++) { String element = list.get(i); } 增强型for循环for (String element : list) { System.out.println(element); } 同时,要提到在遍历过程中修改ArrayList可能导致的问题,比如使用基本for循环删除元素时索引的问题,或者ConcurrentModificationException异常,这时候可能需要引用引用[3]中的内容,说明正确的方法,比如使用迭代器的remove方法,但用户的问题不是删除,所以可能只需要简单提及。 另外,用户提供的引用[2]和[4]可能不太相关,引用[2]是关于ArrayList迭代器的错误,引用[4]是关于遍历HashMap的,但用户的问题是关于ArrayList的,所以可能不需要引用这些,除非有相关的内容需要关联。 最后,生成相关问题。用户要求生成相关问题,可能需要包括遍历的其他方法、性能比较、常见错误等。比如: 1. 使用迭代器遍历ArrayList的方法是什么? 2. 增强型for循环和基本for循环在性能上有何差异? 3. 遍历ArrayList时如何避免ConcurrentModificationException异常? 需要确保问题主题相关,并且能够引导用户进一步学习。 现在,综合以上思考,组织回答的结构,分步骤说明,提供示例代码,引用相关文献,并生成相关问题。同时,确保使用中文,语法正确,数学表达式格式正确(虽然这个问题可能不需要数学表达式,但系统级指令要求所有行内数学表达式用$...$,所以需要注意如果有的话)。</think>### 如何用for循环遍历Java ArrayList 以下是使用for循环遍历Java ArrayList的两种常用方法及示例代码: --- #### **1. 基础for循环(索引遍历)** 通过索引$i$逐项访问元素,使用`list.get(i)`获取元素。 ```java ArrayList<String> list = new ArrayList<>(); list.add("苹果"); list.add("香蕉"); list.add("橙子"); for (int i = 0; i < list.size(); i++) { String element = list.get(i); System.out.println("索引 " + i + ": " + element); } ``` - **优点**:可通过索引操作元素,适合需要修改元素的场景。 - **注意**:遍历时删除元素可能导致索引错位(需倒序遍历或调整索引)[^3]。 --- #### **2. 增强型for循环for-each)** 直接遍历集合元素,语法更简洁。 ```java for (String element : list) { System.out.println("元素: " + element); } ``` - **优点**:代码简洁,无需处理索引。 - **限制**:无法直接修改集合结构(如删除元素),否则会抛出`ConcurrentModificationException`[^2]。 --- #### **遍历时删除元素的正确姿势** 若需遍历时删除元素,建议使用**迭代器**(`Iterator`): ```java Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String element = iterator.next(); if (element.equals("香蕉")) { iterator.remove(); // 安全删除当前元素 } } ``` 此方法可避免索引越界和并发修改异常[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值