報錯示例一:對象
List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); list.add("4"); for(String str : list){ if(!str.equals("1")) { list.remove(str); } } System.out.println(list.size());
錯誤使用二:這種狀況不會報錯,由於最後一個元素未被遍歷到就程序跳出了循環遍歷索引
List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); for(String str : list){ if(!str.equals("1")) { list.remove(str); } } System.out.println(list.size());
方法一:for循環遍歷rem
List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); for (int i = 0; i < list.size(); i++) { String item = list.get(i); if("2".equals(item)) { //邏輯判斷,剔除知足條件的元素 list.remove(item); //元素刪除後,後面的元素位置向前挪一位,位置索引i須要自減一,不然訪問不到後面的元素 i--; } } System.out.println(list.size());
方法二:使用集合的迭代器get
List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); for(Iterator<String> it = list.iterator(); it.hasNext(); ){ if("2".equals(it.next())) { //使用迭代器的刪除方法,不要使用集合對象的刪除方法remove it.remove(); } } System.out.println(list.size());
緣由說明:it
一、若是使用加強for循環進行遍歷,那麼實際上使用的是集合的迭代器進行遍歷,這時若是使用的是集合對象本身的刪除方法,迭代器不知道元素集合發生了變化,進行獲取下一個元素的時候就會爆出錯誤:ConcurrentModificationException,但這裏有一點須要注意,若是遍歷過程當中第一個被刪除的元素處在倒數第二個被遍歷的位置時,程序不會報錯,正常結束。實際的結果是:集合中最後一個元素以前,會調用迭代器的hasNext()方法,該方法發現當前位置索引等於集合元素數量,判斷遍歷結束,跳出循環,實則最後一個元素未被遍歷到。io
二、第一種遍歷刪除方法,是本身控制並調整元素位置索引,只要位置索引控制正確,就能夠正常刪除元素,不然會出現IndexOutOfBoundsExceptionfor循環
三、第二種遍歷刪除直接使用迭代器進行遍歷,並且刪除時使用的迭代器的刪除元素方法,這個刪除方法裏面會對位置索引進行調整,使得迭代器在繼續遍歷查找下一個元素時,不會拋出異常錯誤。List