ArrayList remove注意事项
例子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注意事项的更多相关文章
- 关于arraylist.remove的一些小问题。
public static void main(String[] args) { // TODO Auto-generated method stub ArrayList<Integer> ...
- JDK source 之 ArrayList 需要注意事项
线程安全 ArrayList内部没有实现原子性操作,所以是非线程安全的.如果需要在线程安全的环境下使用List的话,需要使用Vector 或者CopyOnWriteArrayList,具体场景,自行深 ...
- Java中ArrayList remove会遇到的坑
前言 平时最常用的莫过于ArrayList和HashMap了,面试的时候也是问答的常客.先不去管容量.负载因子什么的,就是简单的使用也会遇到坑. Remove 元素 经常遇到的一个场景是:遍历list ...
- 为什么ArrayList remove报错
不报错 List<String> userNames = new ArrayList<String>() {{ add("Hollis"); add(&qu ...
- java ArrayList remove 2 及正确方法
https://www.cnblogs.com/chrischennx/p/9610853.html 正确方式 方法一,还是fori,位置前挪了减回去就行了, remove后i--: public v ...
- java ArrayList remove
packimport java.util.ArrayList;import java.util.List; public class ArrayListRemove { public static v ...
- ArrayList中contains,remove方法返回为false的原因
这几天做一个项目时,遇到ArrayList.remove(Object)方法失败,而ArrayList"包含"删除的对象,这其中的"包含"不是完全包含,请看下面 ...
- 【转载】C#中ArrayList集合类使用Remove方法指定元素对象
ArrayList集合是C#中的一个非泛型的集合类,是弱数据类型的集合类,可以使用ArrayList集合变量来存储集合元素信息,任何数据类型的变量都可加入到同一个ArrayList集合中,在Array ...
- ArrayList中remove方法和set(null)的区别
在分析源码ArrayList.remove()时,偶然发现了一个疑惑的点,就是:源码也是将最后一个对象的引用指向null(源码:elementData[--size] = null; // clear ...
随机推荐
- Usage of API documented as @since 1.6+
报错:即方法是Java1.6才开始有的 File ->Project Structure->Project Settings -> Modules -> Language Le ...
- 小白入门篇:flex布局
--前言 因为这个星期写一个小的项目用到flex布局和grid布局,虽然这两种布局都是兼容性都有问题,但是别急,我觉的以后肯定是会发展并且流行起来的,毕竟google大法好,而且这两个布局真的比一般的 ...
- intellij idea 分屏设置 与快捷键
1.找到分屏功能 File -> setting -> keymap,搜索(注意大小写): Split Vertically 水平分屏 Split Horizontally 垂直分 ...
- 细说JavaScript对象(2):原型对象
JavaScript 并没有类继承模型,而是使用原型对象 prototype 进行原型式继承. 尽管人们经常将此看做是 JavaScript 的一个缺点,然而事实上,原型式继承比传统的类继承模型要更加 ...
- LRC CRC 纵向冗余码校验
LRC CRC 纵向冗余码校验 2010-01-26 11:00:15| 分类: 电气 | 标签: |字号大中小 订阅 1.LRC校验 LRC域是一个包含一个8位二进制值的字节.LRC值由 ...
- lock参数变化吗
多线程应用中经常使用lock,在使用这个关键字的时候,经常有个疑问,如果更改了当时的入参,那么是否会变化呢,下面通过代码实例测试一把 class Program { static void Main( ...
- JSP Response Set Status
JSP Response Set Status In this tutorial you will learn about how to set the HTTP status code in JSP ...
- ElasticSearch 结构化搜索
1.介绍 结构化搜索(Structured search) 是指有关探询那些具有内在结构数据的过程.比如日期.时间和数字都是结构化的:它们有精确的格式,我们可以对这些格式进行逻辑操作. 比较常见的操作 ...
- 获取本机IP,用户代理
1.获取本机IP:http://httpbin.org/ip 2.获取用户代理 https://httpbin.org/user-agent https://httpbin.org/ httpbin( ...
- 编译spark源码及塔建源码阅读环境
编译spark源码及塔建源码阅读环境 (一),编译spark源码 1,更换maven的下载镜像: <mirrors> <!-- 阿里云仓库 --> <mirror> ...