第一种迭代删除方式:

第二种迭代删除方式:

第三种迭代删除:

第四种迭代删除:

第五种迭代删除:

第六种:

ArrayList中remove()方法的机制,首先看源码:

真正的删除操作在fastRemove(),首先定义一个新列表的长度newSize,其值为原列表长度减一 (newS-ze = size-1),然后将 索引 i 之后的数组元素全部向前进一位(System.arraycopy(es, i + 1, es, i, newSize - i)),接着最后一个原数组的最后一个元素置为null(es[size = newSize] = null;)。

所以使用for循环遍历删除的时候,每次循环时都要重新获取ArrayList的长度,并在删除元素之后将索引减1(i--)。

或者倒序删除。

迭代器删除:

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; // prevent creating a synthetic constructor
Itr() {} // 当前迭代指示器是否指向列表末尾
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];
} /**
* 删除
*/
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification(); try {
// 调用fastRemove删除元素
ArrayList.this.remove(lastRet);
// 迭代指示器指向被删除元素所在的索引位置
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
} @Override
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
final int size = ArrayList.this.size;
int i = cursor;
if (i < size) {
final Object[] es = elementData;
if (i >= es.length)
throw new ConcurrentModificationException();
for (; i < size && modCount == expectedModCount; i++)
action.accept(elementAt(es, i));
// update once at end to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
} final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}

黄色部分是关键,删除元素后迭代指示器重新指向 “新” 元素,确保每一个元素都能被迭代指示器 “指” 过。

java ArrayList迭代过程中删除的更多相关文章

  1. java 在循环中删除数组元素

    在写代码中经常会遇到需要在数组循环中删除数组元素的情况,但删除会导致数组长度变化. package com.fortunedr.thirdReport; import java.util.ArrayL ...

  2. Java集合类ArrayList循环中删除特定元素

    在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素. 一种错误的方式: <pre name="code" class="java"&g ...

  3. JAVA循环迭代中删除或添加集合数据报java.util.ConcurrentModificationException错误

    1.写出下面的输出结果 public class test{ public static void main(String [] args) List<String> list = new ...

  4. STL容器迭代过程中删除元素技巧(转)

    1.连续内存序列容器(vector,string,deque) 序列容器的erase方法返回值是指向紧接在被删除元素之后的元素的有效迭代器,可以根据这个返回值来安全删除元素. vector<in ...

  5. Java 遍历List中删除的解决方法

  6. Java循环中删除一个列表元素

    本文主要想讲述一下我对之前看到一篇文章的说法.假设跟你的想法有出入,欢迎留言.一起讨论. #3. 在循环中删除一个列表元素 考虑以下的代码.迭代过程中删除元素: ArrayList<String ...

  7. java:Conllection中的List,ArrayList添加元素,删除元素,输出元素

    java:Conllection中的List,ArrayList添加元素,删除元素,输出元素 //为list接口实例化 List<String> addlist = new ArrayLi ...

  8. Java中删除第一个集合中以某某开头的元素,删除第二个集合中以某某结尾的元素,并合并成一个集合

    import java.util.ArrayList; import java.util.List; public class Test { public static void main(Strin ...

  9. Java ArrayList正确循环添加删除元素方法及分析

    在阿里巴巴Java开发手册中,有这样一条规定: 但是手册中并没有给出具体原因,本文就来深入分析一下该规定背后的思考. 一.foreach循环 foreach循环(Foreach loop)是计算机编程 ...

随机推荐

  1. android中如何自动获取短信验证码

    package com.loaderman.smsbroadcastreceiver; import java.util.regex.Matcher; import java.util.regex.P ...

  2. python之拷贝文件

    做了个小实验, 用于拷贝文件夹下面的jpg. 用于拓展, 可以引入类和方法, 拷贝你指定的任意类型的文件. import os src = 'C:\\Users\\Administrator\\Des ...

  3. Centos 7 安装tomcat并部署jar实录

    本文目的 纯属记录,以备后查. 1.安装JAVA JDK 安装jdk略. 配置JDK,打开/etc/profile文件,在最后添加如下代码: JAVA_HOME=/usr/java/jdk1..0_2 ...

  4. 解决Prism中Region的GetView不起作用问题

    通常情况下在Region中添加View时我们需要先判断View是否在Region中已存在,但如果我们在Region.Add的方法调用不当时,我们在GetView中始终返回Null,原因自然是Add时出 ...

  5. 四十五:数据库之SQLAlchemy之subquery实现复杂查询

    子查询让多个查询变成一个查询,只需要查找一次数据库,性能相对来讲更高效,不用写多个SQL语句就可以实现一些复杂的查询,在SQLAlchemy中要实现一个子查询,应该使用以下步骤:1.将子查询按照传统方 ...

  6. 网易云课堂_C++程序设计入门(下)_第11单元:工欲善其事必先利其器 - STL简介_第11单元 - 单元作业2:OJ编程 - list 与 deque

    第11单元 - 单元作业2:OJ编程 - list 与 deque 查看帮助 返回   温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之 ...

  7. Spring Boot 自定义注册 Servlet、Filter、Listener

    前言 在 Spring Boot 中已经移除了 web.xml 文件,如果需要注册添加 Servlet.Filter.Listener 为 Spring Bean,在 Spring Boot 中有两种 ...

  8. python 正则sub的使用

     self.content = re.sub(r'>|<',lambda x: '&gt' if x.group()[0] == '>' else '&lt' , s ...

  9. 使用注解方式搭建SpringMVC

    1.以前搭建Spring MVC 框架一般都使用配置文件的方式进行,相对比较繁琐.spring 提供了使用注解方式搭建Spring MVC 框架的方式,方便简洁.使用Spring IOC 作为根容器管 ...

  10. 小记---------FLUM负载均衡配置

    sink group允许组织多个sink到一个实体上,sink processors能够提供在组内所有sink之间实现负载均衡的能力,而且在失败的情况下能够进行故障转移从一个sink到另一个sink, ...