1.普通for循環的情況
package com.wangdao.generic;
import java.util.ArrayList;
public class ForEachDemo2 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("b");
list.add("d");
//1.普通for循環
for(int i = 0; i < list.size(); i++){
if("b".equals(list.get(i))){
list.remove(i); //通過索引刪除元素
}
}
System.out.println(list);
}
}
上面這段程序的結果是[a, b, c, d],並沒有把所有的b都刪除,這是爲什麼呢?
如果把兩個挨着的b註釋一個,就發現所有的b被刪除了,這時候可以總結一個規律,兩個相同的元素挨着的時候用普通for循環只會刪除一個。需要用內存圖去解決這個問題。
package com.wangdao.generic;
import java.util.ArrayList;
public class ForEachDemo2 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
// list.add("b");
list.add("c");
list.add("b");
list.add("d");
//1.普通for循環
for(int i = 0; i < list.size(); i++){
if("b".equals(list.get(i))){
list.remove(i); //通過索引刪除元素
}
}
System.out.println(list);
}
}
起初內存狀態是這樣的。索引在0的位置上
當i到1的位置時,發現"b".equals(list.get(i))這條語句成立,於是刪除b元素,由於ArrayList的屬性,其長度可以自己變化,所以後面的元素整體向前移動了一個位置,這時候第二個b到達索引爲1的位置,但是執行完循環語句過後,就執行i++操作,就把這個元素跳過去了,去執行判斷下一個元素。
這時候我們需要做的就是在循環語句中加上i減減這條語句,先把索引往前退一個位置,之後再執行i++,代碼如下:
package com.wangdao.generic;
import java.util.ArrayList;
public class ForEachDemo2 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("b");
list.add("d");
//1.普通for循環
for(int i = 0; i < list.size(); i++){
if("b".equals(list.get(i))){
list.remove(i); //通過索引刪除元素
i--; //如果上面條件成立,就先回撤一個索引
}
}
System.out.println(list);
}
}
2.迭代器方法
package com.wangdao.generic;
import java.util.ArrayList;
public class ForEachDemo2 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("b");
list.add("d");
//2.迭代器方法
//首先獲取迭代器
Iterator<String> it = list.iterator();
while(it.hasNext()){
if("b".equals(it.next())){
//list.remove("b");//ConcurrentModificationException 不能用集合的刪除方法,因爲在迭代過程中集合的修改會導致併發修改異常
it.remove();
}
}
/*for(Iterator<String> it = list.iterator();it.hasNext();) { //另一種寫作方法
if ("b".equals(it.next())) {
//list.remove("b");//ConcurrentModificationException 不能用集合的刪除方法,因爲在迭代過程中集合的修改會導致併發修改異常
it.remove();
}
}*/
System.out.println(list);
}
}
3.增強for循環
package com.wangdao.generic;
import java.util.ArrayList;
public class ForEachDemo2 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("b");
list.add("d");
//3.增強for循環
for(String s: list){
if("b".equals(s)){
list.remove("b"); //固定格式,只能用集合的刪除方法,不能刪除掉,會提示併發修改異常,因爲底層是迭代器實現的
}
}
System.out.println(list);
}
}
綜上所述:
- 普通for循環 :可以刪除,但是索引要自減
- 迭代器:可以刪除,但必須用迭代器中自身的remove方法刪除,否則出現併發修改異常
- 增強for循環:不能刪除,只能遍歷,因爲其底層依賴的是迭代器方法