为什么for循环中删除元素会报错
有时会遇到这样的业务需要,在 for 循环中删除列表元素,比如下面的例子。
List<User> userList = userDao.getUserList();
for(int i = 0; i < userList.size(); i++){
User user = userList.get(i);
// 进行退款操作,若退款失败,从列表中删除
boolean withdraw = true; // 此处省略业务代码
if(withdraw){
userList.remove(user);
}
}
这样的代码是不报错的,也不会抛出异常。但是当用到迭代器时,会报错。
List<User> userList = userDao.getUserList();
for(User user : userList){
// 进行退款操作,若退款失败,从列表中删除
boolean withdraw = true; // 此处省略业务代码
if(withdraw){
userList.remove(user);
}
}
for(User user : userList){} ,这样的代码,可能会抛出异常的。
这个原因是迭代器遍历时,删除未遍历的元素时,源码层面会报错。
具体原因,回头再写一篇文章详细说明。
本篇文章的重点是说 for(int i = 0; i < userList.size(); i++){} 这样不报错,当我写了个demo去验证时,出了幺蛾子。
public static void main(String[] args) {
String test = "1,2,3,4,5,6,7";
List<String> testList = Arrays.asList(test.split(","));
log.info("testList:{}",testList);
for(int i = 0; i < testList.size(); i++){
String temp = testList.get(i);
if("3".equals(temp)){
testList.remove(temp);
}
}
log.info("testList:{}",testList);
}
我知道for循环中,这样删除元素,应该是不报错的,可是demo运行报错了。
然后我就开始疑惑了,为什么会这样呢? for 循环里,不可以删除么。当我改了一行代码后,以运行了一次
List<String> testList = Arrays.asList(test.split(","));
List<String> testList = new ArrayList<>(Arrays.asList(test.split(","))) ;
public static void main(String[] args) {
String test = "1,2,3,4,5,6,7";
List<String> testList = new ArrayList<>(Arrays.asList(test.split(","))) ;
log.info("testList:{}",testList);
for(int i = 0; i < testList.size(); i++){
String temp = testList.get(i);
if("3".equals(temp)){
testList.remove(temp);
}
}
log.info("testList:{}",testList);
}
这个运行结果
testList:[1, 2, 3, 4, 5, 6, 7]
testList:[1, 2, 4, 5, 6, 7]
Process finished with exit code 0
完美运行了,结果符合我预期,for 循环中,删除了一个元素。
我点开了,Arrays.asList 的源码,返回值就是 ArrayList
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
我感到头大了,头大的是,现在为什么不报错了。下边这两行代码
用第一行报错,用第二行不报错, Arrays.asList 返回的就是一个ArrayList
List<String> testList = Arrays.asList(test.split(","));
List<String> testList = new ArrayList<>(Arrays.asList(test.split(","))) ;
我提醒自己,不是见鬼了,不是见鬼了,一定是我还有东西没想到。
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
当我点击进行这个new ArrayList<>(a)时,它居然没有跳转到别的类,而是留在了当前类java.util.Arrays 中,
尼马, Arrays这个类中,有一个内部类,叫 ArrayList。此ArrayList,非彼ArrayList。
这时,我才想起来,以前看过文章,提到过 Arrays的这个内部类,今天真的没想起来。
List testList = Arrays.asList(test.split(",")); 用这个的时候,实际调用的是,Arrays这个类的内部类 ArrayList
内部类中,没有remove 这方法。
本文地址:https://blog.csdn.net/every__day/article/details/109270953
上一篇: 冻鸡腿要不要焯水?
下一篇: JDK8新特性学习总结