第一种迭代删除方式:

第二种迭代删除方式:

第三种迭代删除:

第四种迭代删除:

第五种迭代删除:

第六种:

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. [SPSS]学习笔记--数据分布形状描述

    以下内容摘自:公众号- SPSS生活统计学 保存做复习之用. 峰度(Kurtosis) 峰度是描述总体(样本)中所有取值分布形态陡缓程度的统计量.通过计算可以得到峰度系数,峰度系数与分布形态的关系是: ...

  2. Python_序列对象内置方法详解_String

    目录 目录 前言 软件环境 序列类型 序列的操作方法 索引调用 切片运算符 扩展切片运算符 序列元素的反转 连接操作符 重复运算符 成员关系符 序列内置方法 len 获取序列对象的长度 zip 混合两 ...

  3. Dojo入门:初识Dojo

      Dojo的全称是Dojo Toolkit,始创于2004年,是当前各种蓬勃发展的JS工具包中的佼佼者.Dojo 为富互联网应用程序(RIA) 的开发提供了完整的端到端的解决方案,包括核心的 Jav ...

  4. Unity旋转问题的总结

    1.物体的直接旋转 transform.Rotate();这个函数是在当前状态下网某个方向旋转.并且这里可以设置为世界空间或者自身空间. transform.rotation;这里可以通过直接定义一个 ...

  5. AJAX得基本使用

    直接上案例:

  6. [转帖]IIS7 应用程序池的 托管管道模式与集成模式小结

    IIS7 应用程序池的 托管管道模式与集成模式小结 https://www.jb51.net/article/26311.htm IIS7的一些问题. 关注脚本之家微信公众号(jb51net) 每周都 ...

  7. RabbitMQ入门教程(十):队列声明queueDeclare

    原文:RabbitMQ入门教程(十):队列声明queueDeclare 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https:// ...

  8. for XML path 使用技巧

    FOR XML PATH 是sqlserver数据库的语法,能将查询出的数据转换成xml格式的数据. 首先,我们来看一个正常的查询: SELECT TOP 2 id, name,crDate FROM ...

  9. Jquery复习(五)之append()、appendTo()、prepend()、prependTo()、after()、before()易忘点

    添加元素的方法 append().appendTo().prepend().prependTo().after().before() 通过 append() .appendTo().prepend() ...

  10. BZOJ 4141 [Thu Summer Camp 2013]魔塔

    权限题qwq 以下设值域大小为\(m\) 先考虑枚举攻击力,因为首先攻击力决定每个怪物的攻击次数,然后对于每个怪物,攻击次数为\(\lceil\frac{hp_i}{ATK-def_i}\rceil\ ...