例子1:

List<Integer>list=new ArrayList<>();
list.add(1);
list.add(2);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
for(int i=0;i<list.size();i++){
if(list.get(i)%2==0){
list.remove(list.get(i));
}
}
System.out.println(list);

输出结果:

[1, 2, 3, 5]

分析:
第三个元素没有remove 掉,跟踪:
第一次循环
i=0 size=5 当前元素=1 不移除元素
i=1 size=5 当前元素=2 移除元素
i=2 size=4 当前元素=3 不移除元素

在remove 的过程中 size 是移动的,所以 第三个元素给漏掉了

例子2:

List<Integer>list=new ArrayList<>();
list.add(1);
list.add(2);
list.add(2);
list.add(3);
list.add(4);
list.add(5); System.out.println(list);*/ for (Integer a:list){
if(a == 2){
list.remove(a);
}
}

  

抛出异常:

java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at com.student.eureka1.StudentEureka1ApplicationTests.contextLoads(StudentEureka1ApplicationTests.java:31)

  

原因:
抛出异常代码

public E next() {
checkForComodification();
  int i = cursor;
  if (i >= size)
    throw new NoSuchElementException();
  Object[] elementData = ArrayList.this.elementData;
  if (i >= elementData.length)
    throw new ConcurrentModificationException();
    cursor = i + 1;
    return (E) elementData[lastRet = i];
} final void checkForComodification() {
// 是因为 modCount != expectedModCount 不相等
  if (modCount != expectedModCount)
  throw new ConcurrentModificationException();
}

  

在使用for(Object obj:objList) 这种增强for 循环的时候,每次遍历会进行hasNext 判断,它会创建 List的遍历器Iterator ,在创建的时候它会将 modCount 赋值给 expectedModCount 。并且调用Iterator 的 next 方法。

在没有调用 list.remove(a); 方法前,expectedModCount 和 modCount是相等的。

当调用后    注意 list.remove(a); 调用的不是Iterator 的remove 方法,而是 ArrayList的remove 方法, ArrayList的remove 方法 只会更新 modCount 值,不会更新expectedModCount 值,所以不相等报错

(简单点就是说:你用了Iterator 遍历 但是在里面不是用Iterator  的 remove 方法导致)

private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount; public boolean hasNext() {
  return cursor != size;
} @SuppressWarnings("unchecked")
public E next() {
  checkForComodification();
  int i = cursor;
  if (i >= size)
    throw new NoSuchElementException();
  Object[] elementData = ArrayList.this.elementData;
  if (i >= elementData.length)
    throw new ConcurrentModificationException();
  cursor = i + 1;
  return (E) elementData[lastRet = i];
}

ArrayList remove注意事项的更多相关文章

  1. 关于arraylist.remove的一些小问题。

    public static void main(String[] args) { // TODO Auto-generated method stub ArrayList<Integer> ...

  2. JDK source 之 ArrayList 需要注意事项

    线程安全 ArrayList内部没有实现原子性操作,所以是非线程安全的.如果需要在线程安全的环境下使用List的话,需要使用Vector 或者CopyOnWriteArrayList,具体场景,自行深 ...

  3. Java中ArrayList remove会遇到的坑

    前言 平时最常用的莫过于ArrayList和HashMap了,面试的时候也是问答的常客.先不去管容量.负载因子什么的,就是简单的使用也会遇到坑. Remove 元素 经常遇到的一个场景是:遍历list ...

  4. 为什么ArrayList remove报错

    不报错 List<String> userNames = new ArrayList<String>() {{ add("Hollis"); add(&qu ...

  5. java ArrayList remove 2 及正确方法

    https://www.cnblogs.com/chrischennx/p/9610853.html 正确方式 方法一,还是fori,位置前挪了减回去就行了, remove后i--: public v ...

  6. java ArrayList remove

    packimport java.util.ArrayList;import java.util.List; public class ArrayListRemove { public static v ...

  7. ArrayList中contains,remove方法返回为false的原因

    这几天做一个项目时,遇到ArrayList.remove(Object)方法失败,而ArrayList"包含"删除的对象,这其中的"包含"不是完全包含,请看下面 ...

  8. 【转载】C#中ArrayList集合类使用Remove方法指定元素对象

    ArrayList集合是C#中的一个非泛型的集合类,是弱数据类型的集合类,可以使用ArrayList集合变量来存储集合元素信息,任何数据类型的变量都可加入到同一个ArrayList集合中,在Array ...

  9. ArrayList中remove方法和set(null)的区别

    在分析源码ArrayList.remove()时,偶然发现了一个疑惑的点,就是:源码也是将最后一个对象的引用指向null(源码:elementData[--size] = null; // clear ...

随机推荐

  1. (3)oracle建用户、建表、权限、命名空间

    一.表空间 创建表空间 create tablespace  ts001  datafile ‘d:\test\a.dbf’ size 20m uniform size 128k; 使用表空间 cre ...

  2. 了解RxJava以及如何在Android应用中使用它

    如果你在阅读这篇文章,相信你一定很想了解RxJava以及如何在Android应用中使用它.可能你已经见过RxJava的代码了,但仍然有些疑惑,愿你能在这篇文章里找到答案. 当我第一次使用RxJava的 ...

  3. java 的""和null的区别

    null和""的区别 问题一: null和""的区别 String s=null; string.trim()就会抛出为空的exception String s ...

  4. python开发微信支付学习记录(转)

    前言 微信支付是由微信及财付通联合推出的移动支付创新产品.如今,随着微信支付的全面开放,相关需求也越来越多,很多开发人员进行微信支付开发及商家申请微信支付时,面临着诸多疑惑. 要想开发顺利进行,首先要 ...

  5. ARCGIS FLEX API加载google地图、百度地图、天地图(转)

    http://www.cnblogs.com/chenyuming507950417/ Flex加载google地图.百度地图以及天地图作底图 一  Flex加载Google地图作底图 (1)帮助类G ...

  6. Shell--变量内容的删除、替代与替换

    1. 变量内容的删除与替换 #代表由前面开始删除,所以这里便由开始的/删起,*来代替0到无穷多个任意字符 %由后面向前删除变量内容 例如:echo ${path%:*bin}删除最有一个目录,即从:到 ...

  7. spring aop expression支持多个表达式配置

    <!-- 配置那些类的方法进行事务管理 --> <aop:config> <aop:pointcut id="allServiceMethod" ex ...

  8. ES6中的迭代器(Iterator)和生成器(Generator)(一)

    用循环语句迭代数据时,必须要初始化一个变量来记录每一次迭代在数据集合中的位置,而在许多编程语言中,已经开始通过程序化的方式用迭代器对象返回迭代过程中集合的每一个元素 迭代器的使用可以极大地简化数据操作 ...

  9. 2017.6.30 IDEA插件--gsonfomat的安装与使用

    参考来自:http://www.cnblogs.com/1024zy/p/6370305.html 1.安装 2.使用 (1)新建一个空类 (2)在空类里按快捷键:alt+s,打开gsonformat ...

  10. Laravel之Elixir

    一.Elixir安装和设置 1.安装node.js 2.安装Gulp 作为全局NPM 包 npm install --global gulp 3.最后,在新安装的Laravel 根目录下,你会发现有一 ...