例子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. Usage of API documented as @since 1.6+

    报错:即方法是Java1.6才开始有的 File ->Project Structure->Project Settings -> Modules -> Language Le ...

  2. 小白入门篇:flex布局

    --前言 因为这个星期写一个小的项目用到flex布局和grid布局,虽然这两种布局都是兼容性都有问题,但是别急,我觉的以后肯定是会发展并且流行起来的,毕竟google大法好,而且这两个布局真的比一般的 ...

  3. intellij idea 分屏设置 与快捷键

    1.找到分屏功能 File -> setting -> keymap,搜索(注意大小写):   Split Vertically 水平分屏   Split Horizontally 垂直分 ...

  4. 细说JavaScript对象(2):原型对象

    JavaScript 并没有类继承模型,而是使用原型对象 prototype 进行原型式继承. 尽管人们经常将此看做是 JavaScript 的一个缺点,然而事实上,原型式继承比传统的类继承模型要更加 ...

  5. LRC CRC 纵向冗余码校验

    LRC CRC 纵向冗余码校验   2010-01-26 11:00:15|  分类: 电气 |  标签: |字号大中小 订阅  1.LRC校验  LRC域是一个包含一个8位二进制值的字节.LRC值由 ...

  6. lock参数变化吗

    多线程应用中经常使用lock,在使用这个关键字的时候,经常有个疑问,如果更改了当时的入参,那么是否会变化呢,下面通过代码实例测试一把 class Program { static void Main( ...

  7. JSP Response Set Status

    JSP Response Set Status In this tutorial you will learn about how to set the HTTP status code in JSP ...

  8. ElasticSearch 结构化搜索

    1.介绍 结构化搜索(Structured search) 是指有关探询那些具有内在结构数据的过程.比如日期.时间和数字都是结构化的:它们有精确的格式,我们可以对这些格式进行逻辑操作. 比较常见的操作 ...

  9. 获取本机IP,用户代理

    1.获取本机IP:http://httpbin.org/ip 2.获取用户代理 https://httpbin.org/user-agent https://httpbin.org/ httpbin( ...

  10. 编译spark源码及塔建源码阅读环境

    编译spark源码及塔建源码阅读环境 (一),编译spark源码 1,更换maven的下载镜像: <mirrors> <!-- 阿里云仓库 --> <mirror> ...