例子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. poj3311(状态压缩DP)

    poj3311 题意 给出一个矩阵,i 行 j 列表示位置 i 到 j 的时间. 求从 0 点出发经过 1 到 n 所有点后并返回 0 点最短耗时. 分析 先用 Floyd 算法,求出两点之间最短路, ...

  2. Find intersection of two sorted arrays

    共有三种思路. 哈希表. 将较小的那个数组中的所有元素存在哈希表中.然后依次验证另一个数组中的数字是否有出现过.时间复杂度O(m + n),空间复杂度O(min(m, n)) 二分搜索法 将较小的那个 ...

  3. 图床plus演示 | 图床及在线分享演示文稿工具

    文章目录 关于图床 什么是图床? 墙内 墙外 关于在线分享演示文稿 在线分享演示文稿 工具分享 待补充 关于图床 什么是图床? 这并不是一个多么高大上的名词概念!用比较通俗的话来说,当你在撰写新文章时 ...

  4. maven配置memcached.jar

    由于目前java memcached client没有官方的maven repository可供使用,因此使用时需要手动将其安装到本地repository. java memcached client ...

  5. 用Xcode6的Leaks检测内存泄漏

    用xcode打开项目之后,选择Product - Profile: 在弹出的窗口中选择Leaks: 然后在设备解锁的情况下,选择Leaks再点击左上角的红色按钮开始运行APP: 红色的柱子表示有内存泄 ...

  6. linux-启动脚本-souce与sh

    source:        在当前shell程序中执行,  因此当前shell程序中的变量和环境变量,均可见.   执行的脚本,能更新到当前shell程序. sh:            开启一个新 ...

  7. .net的远程调用

    .Net远程调用(转自:http://www.cnblogs.com/omilan/articles/3191378.html) 看到了这.net远程调用的讲解,觉得不错,拿来分享!! .Net对于远 ...

  8. ASP.NET MVC学习---(五)MVC初体验

    经过之前n多的铺垫 我们已经大概了解了这个姓m名vc的家伙了 那么今天我们就来体验一把 怎么体验呢? 就来做一个小例子吧~ mvc增删改查的例子 数据库还是之前我们的老朋友 关系图: 表中的数据已填好 ...

  9. 代码验证C#执行”文件打开关闭操作“耗时

    2017-04-19 部门经理习惯用C#做数据清洗,遇到个需要验证的问题,在一个万次左右循环内对文件执行打开关闭操作,比在循环前打开文件.循环后关闭文件耗时多多少. using System; usi ...

  10. window.onerror事件用来自定义错误处理

    Event reference:      https://developer.mozilla.org/en-US/docs/Web/Events http://w3c.github.io/html/ ...