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 ...
随机推荐
- HDU 5732 Subway(2016多校1J,树的重心 + 哈希)
题目链接 2016多校1 Problem J 题意 给定两棵相同的树,但是编号方案不同.求第一棵树上的每个点对应的第二棵树上的点.输出一种方案即可. 首先确定树的直径的中点.两棵树相等意味着两棵树 ...
- schema get_ddl
select dbms_metadata.get_ddl('INDEX','INDEX_CC_TAXID','CACS9DBSIT1') from dual; select dbms_metadata ...
- redis的lua脚本拓展,返回nil及其判断
redis自带的lua脚本 127.0.0.1:6379> hget team wyc "{\"name\":\"wyycc\",\" ...
- Hadoop 2.2.0 Job源代码阅读笔记
本文所有涉及的内容均为2.2.0版本中呈现. 概述: Job在创建Job并且提交的人的眼中,可以在创建的时候通过配置Job的内容,控制Job的执行,以及查询Job的运行状态.一旦Job提交以后,将不能 ...
- 利用json2csharp快速生成C#类
有的时候,我们需要将一些Json格式的字符串反序列化为.Net对象,虽然有强大的Json.net可以帮助我们快速完成这一操作.但首先仍需要我们根据Json数据手动编写C#类,这也是一件比较枯燥而容易出 ...
- SYSPROCESSES 查看连接
原文:SYSPROCESSES 查看连接 SELECT at.text,sp.* FROM[Master].[dbo].[SYSPROCESSES] sp CROSS APPLY sys.dm_exe ...
- JAVA常见算法题(十六)
package com.xiaowu.demo; //猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个: //第二天早上又将剩下的桃子吃掉一半,而且又多吃了一个. //以后 ...
- [置顶]
kubernetes--资源管理
概念 默认情况下,kubernetes不会限制pod等资源对象使用系统资源,单个pod或者容器可以无限制使用系统资源. kubernetes的资源管理分为资源请求(request)和资源限制(limi ...
- numpy自动生成数组
1 np.arange(),类似于range,通过指定开始值,终值和步长来创建表示等差数列的一维数组,注意该函数和range一样结果不包含终值. >>> np.arange(10) ...
- 设计模式之适配器模式(php实现)
/* github地址:https://github.com/ZQCard/design_pattern * 适配器模式:将一个类的接口转换成客户希望的另外一个接口. * 适配器模式使得原本由于接口不 ...