位置:首页 > Java > foreach遍历集合的用法与常见问题解析

foreach遍历集合的用法与常见问题解析

时间:2026-08-18  |  作者:318050  |  阅读:0

Iterator当然也能完成集合元素的遍历,但真到写代码时,这种写法多少显得有些繁琐。正因为如此,从JDK 5开始,Ja va专门提供了foreach循环,目的很直接,就是把这件事写得更简单一些。它本质上是一种更简洁的for循环,也常被称为增强for循环。通常来说,foreach循环主要用来遍历数组或集合中的元素,具体语法格式如下:

for(容器中元素类型 临时变量 :容器变量) {
  // 执行语句
}

从上面的格式可以看出,与for循环相比,foreach循环不需要获得容器的长度,也不需要根据索引访问容器中的元素,但它会自动遍历容器中的每个元素。接下来通过一个案例对foreach循环进行详细讲解,如文件1所示。

文件1 Example04.Ja va

 1    import ja va.util.ArrayList;
 2    public class Example04 {
 3        public static void main(String[] args) {
 4            ArrayList list = new ArrayList();     
 5            list.add("data_1");                     
 6            list.add("data_2");
 7            list.add("data_3");        
 8             // 使用foreach循环遍历集合
 9            for (Object obj : list) {    
 10                 System.out.println(obj);    // 取出并打印集合中的元素
 11            }
 12        }
 13    }

运行结果如图1所示。

foreach遍历集合的用法与常见问题解析_wishdown.com

图1 运行结果

通过文件1可以看出,foreach循环遍历集合的语法非常简洁,没有循环条件,也没有迭代语句,所有这些工作都交给JVM去执行了。foreach循环的次数是由容器中元素的个数决定的,每次循环时,foreach中都通过变量将当前循环的元素记住,从而将集合中的元素分别打印出来。

脚下留心:

1.foreach循环虽然书写起来很简洁,但在使用时也存在一定的局限性。当使用foreach循环遍历集合和数组时,只能访问集合中的元素,不能对其中的元素进行修改,接下来以一个String类型的数组为例来进行演示,如文件2所示。

文件2 Example05.ja va

 1    public class Example05 {
 2        static String[] strs = { "aaa", "bbb", "ccc" };
 3        public static void main(String[] args) {
 4            // 1、foreach循环遍历数组
 5            for (String str : strs) {
 6                str = "ddd";
 7            }
 8            System.out.println("foreach循环修改后的数组:" + strs[0] + ","
 9                                     + strs[1] + "," + strs[2]);
 10            // 2、for循环遍历数组
 11            for (int i = 0; i < strs.length; i++) {
 12                strs[i] = "ddd";
 13            }
 14            System.out.println("普通for循环修改后的数组:" + strs[0] + ","
 15                                   + strs[1] + "," + strs[2]);
 16        }
 17    }

运行结果如图2所示。

foreach遍历集合的用法与常见问题解析_wishdown.com

图2 运行结果

文件2里分别用了foreach循环和普通for循环来修改数组元素。看运行结果就会发现,foreach这条路实际上改不了数组里元素本身的值。原因在于第6行代码中的str = "ddd",本质上只是让临时变量str重新指向了一个新的字符串,和数组中的原始元素并没有建立修改关系。相比之下,普通for循环就不一样了,它可以通过索引直接定位到数组中的元素,因此也就能够真正把对应元素的值改掉。

2.在使用Iterator迭代器对集合中的元素进行迭代时,如果调用了集合对象的remove()方法去删除元素,会出现异常。接下来通过一个案例来演示这种异常,如文件3所示。

文件3 Example06.ja va

 1    import ja va.util.ArrayList;
 2    import ja va.util.Iterator;
 3    public class Example06 {
 4        public static void main(String[] args) {
 5        ArrayList list = new ArrayList();     
 6            list.add("Jack");
 7            list.add("Annie");
 8            list.add("Rose");
 9            list.add("Tom");
 10            Iterator it = list.iterator();   // 获得Iterator对象
 11            while (it.hasNext()) {            // 判断该集合是否有下一个元素
 12                Object obj = it.next();      // 获取该集合中的元素
 13                if ("Annie".equals(obj)) {  // 判断该集合中的元素是否为Annie
 14                    list.remove(obj);        // 删除该集合中的元素
 15                }
 16            }
 17             System.out.println(list);
 18        }
 19    }

运行结果如图3所示。

foreach遍历集合的用法与常见问题解析_wishdown.com

图3 运行结果

文件3在运行时出现了并发修改异常ConcurrentModificationException。这个异常是迭代器对象抛出的,出现异常的原因是集合中删除了元素会导致迭代器预期的迭代次数发生改变,导致迭代器的结果不准确。

为了解决上述问题,可以采用两种方式,具体如下:

第一种方式:从业务逻辑上讲只想将元素Annie删除,至于后面还有多少元素我们并不关心,所以只需找到该元素后跳出循环不再迭代即可,也就是在第14行代码下面增加一个break语句,代码如下:

if ("Annie".equals(obj)) {
    list.remove(obj);
    break;
}

在使用break语句跳出循环以后,由于没有继续使用迭代器对集合中的元素进行迭代,因此,集合中删除元素对程序没有任何影响,不会出现异常。

第二种方式:如果需要在集合的迭代期间对集合中的元素进行删除,可以使用迭代器本身的删除方法,将文件3中第14行代码替换成it.remove()即可解决这个问题,代码如下:

if ("Annie".equals(obj)) { 
    it.remove(); 
}

替换代码后再次运行程序,运行结果如图4所示。

foreach遍历集合的用法与常见问题解析_wishdown.com

图4 运行结果

从图4可以看出,元素Annie确实被删除了,并且没有出现异常。因此可以得出结论,调用迭代器对象的remove()方法删除元素所导致的迭代次数变化,对于迭代器对象本身来讲是可预知的。

来源:整理自互联网
免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多