java容器中遍歷循環Iterator 和 Foreach 循環


最近遇到這樣一個問題,要刪除一個集合中的某個元素,該怎么解決?

我自己寫了兩段代碼來刪除,都報了一個錯java.util.ConcurrentModificationException;為了讓更多可能沒注意到這個點的程序猿注意一下,我在這里分享下~

先看代碼

 1 package com.zwt1234;
 2 
 3 import java.util.HashSet;
 4 import java.util.Iterator;
 5 import java.util.Set;
 6 
 7 public class IteratorTest {
 8     public static void main(String[] args) {
 9         Set<Object> s = new HashSet<Object>(0);
10         s.add(new Man("小明", 12));
11         s.add(new Man("小李", 15));
12         s.add(new Man("小華", 21));
13         validateIterator(s);
14 //        validateForeach(s);
15     }
16     
17     /**
18      * 驗證Iterator接口的方法
19      * iterator進入循環后,相當於線程上了一把鎖,誰都不讓進,只能用iterator自己的對象操作數據
20      * 因此下面用s.remove(man)是,程序報錯
21      * @param s
22      */
23     public static void validateIterator(Set<Object> s) {
24         Iterator<Object> iter = s.iterator();
25         while (iter.hasNext()) {
26             Man man = (Man)iter.next();
27             System.out.println(man);
28             if (man.name.equals("小李")) {
29                 iter.remove();
30                 // s.remove(man);//此時程序報錯java.util.ConcurrentModificationException
31             }
32         }
33         System.out.println("------------------------");
34         /*
35          * 執行上面刪除操作后重新打印s集合中元素,印證操作
36          */
37         iter = s.iterator();
38         while (iter.hasNext()) {
39             System.out.println(iter.next());
40         }
41     }
42     
43     /**
44      * 驗證foreach循環
45      * foreach循環相對iterator在查詢上面更加方便了,因為代碼量少了;
46      * 但是在歲數據操作上面比不過iterator
47      * @param s
48      */
49     public static void validateForeach(Set<Object> s) {
50         for (Object obj:s) {
51             Man man = (Man)obj;
52             System.out.println(man);
53             if (man.name.equals("小李")) {
54                 s.remove(man);//這里同樣是不讓刪除的,因為foreach循環底層就是用的iterator的實現方式
55             }
56         }
57     }
58 }
59 
60 class Man {
61     String name;
62     int age;
63 
64     Man(String name, int age) {
65         this.name = name;
66         this.age = age;
67     }
68 
69     @Override
70     public String toString() {
71         return "Man [name=" + name + ", age=" + age + "]";
72     }
73 }
View Code

下面我們來分析下我們這段代碼

  1.首先我用,Iterator來實現的刪除,開始的時候,在遍歷到存入的對象名為小李的時候,我就讓這個對象,在Set集合s中刪除,在if語句里面,面對2個問題,集合s有給我們提供一個remove()方法,還有iterator也給我們提供了一個remove()方法,我們用哪個?

  最開始的時候我選用的是Set集合給的方法,可是在運行的時候,結果就報錯了,而改用iterator提供的方法是可以正確運行的,正常刪除了我所需要刪除的對象。

  結果總結說明在使用iterator迭代器的時候,我們需要刪除集合中數據,使用的應該是Iterator的remove()方法,因為使用iterator的時候,就相當於給線程給資源上了一把鎖,只有iterator本身可以去刪除數據,而集合線程是無法在iterator占用資源的時候對資源進行刪除的。

  2.同樣的foreach增強for循環的實現刪除的時候,我也去實現了下。

  因為foreach循環沒有給我們提供remove()方法,因此我們直接使用Set集合里面給我們提供的刪除方法,發現也是會報和iterator同樣的錯誤,因此,證明foreach循環是不適合進行數據的刪除的

  (對於上面的代碼操作結果,就請大家copy一下,直接運行就能查看結果了,這里我就不展示了)

  3.最后總結:①相比於foreach,迭代器iterator的使用略顯繁瑣;

        ②相比於foreach,迭代器iterato在對數據的操控顯然比foreach要靈活。

 

  最后的最后,上面的總結知識博主自己的個人見解,有不周到的地方,或者錯誤的地方,請大家指正,謝謝~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM