集合框架(三种循环能否删除元素)java实现
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循环:不能删除,只能遍历,因为其底层依赖的是迭代器方法