java ArrayList迭代过程中删除
第一种迭代删除方式:
第二种迭代删除方式:
第三种迭代删除:
第四种迭代删除:
第五种迭代删除:
第六种:
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迭代过程中删除的更多相关文章
- java 在循环中删除数组元素
在写代码中经常会遇到需要在数组循环中删除数组元素的情况,但删除会导致数组长度变化. package com.fortunedr.thirdReport; import java.util.ArrayL ...
- Java集合类ArrayList循环中删除特定元素
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素. 一种错误的方式: <pre name="code" class="java"&g ...
- JAVA循环迭代中删除或添加集合数据报java.util.ConcurrentModificationException错误
1.写出下面的输出结果 public class test{ public static void main(String [] args) List<String> list = new ...
- STL容器迭代过程中删除元素技巧(转)
1.连续内存序列容器(vector,string,deque) 序列容器的erase方法返回值是指向紧接在被删除元素之后的元素的有效迭代器,可以根据这个返回值来安全删除元素. vector<in ...
- Java 遍历List中删除的解决方法
- Java循环中删除一个列表元素
本文主要想讲述一下我对之前看到一篇文章的说法.假设跟你的想法有出入,欢迎留言.一起讨论. #3. 在循环中删除一个列表元素 考虑以下的代码.迭代过程中删除元素: ArrayList<String ...
- java:Conllection中的List,ArrayList添加元素,删除元素,输出元素
java:Conllection中的List,ArrayList添加元素,删除元素,输出元素 //为list接口实例化 List<String> addlist = new ArrayLi ...
- Java中删除第一个集合中以某某开头的元素,删除第二个集合中以某某结尾的元素,并合并成一个集合
import java.util.ArrayList; import java.util.List; public class Test { public static void main(Strin ...
- Java ArrayList正确循环添加删除元素方法及分析
在阿里巴巴Java开发手册中,有这样一条规定: 但是手册中并没有给出具体原因,本文就来深入分析一下该规定背后的思考. 一.foreach循环 foreach循环(Foreach loop)是计算机编程 ...
随机推荐
- 使用ViewPager实现广告自动轮播的效果
package com.loaderman.viewpgerlunbodemo; import android.os.Bundle; import android.os.Handler; import ...
- 哈希表 HashTable(又名散列表)
简介 其实通过标题上哈希表的英文名HashTable,我们就可以看出这是一个组合的数据结构Hash+Table. Hash是什么?它是一个函数,作用可以通过一个公式来表示: index = HashF ...
- Opencv中copyTo()函数的使用方法
在Mat矩阵类的成员函数中copyTo(roi , mask)函数是非常有用的一个函数,尤其是后面的mask可以实现蒙版的功能,我们用几个实例来说明它的作用.我们要注意mask的数据类型,必须是CV_ ...
- 数据测试002:利用Jmeter推送测试数据(上)
数据测试002:利用Jmeter推送测试数据(上) 刚才用Jmeter配置一下MySQL数据库花了点时间,好在最后都解决了,注意下面几个问题: 1)没有配置 “Cannot load JDBC dr ...
- Laravel中一些要记住 的写法
模型篇: 1.根据数据库部分URL返回完整的URL public function getImageUrlAttribute() { // 如果 image 字段本身就已经是完整的 url 就直接返回 ...
- HDU 1074 Doing Homework (状压DP)
Doing Homework Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- docker安装详解
系统要求 64位操作系统 Linux kernel大于等于3.10 CentOS 7以及以上版本 yum安装 移除旧版本docker信息 # yum -y remove docker docker-c ...
- Java 读取Json文件内容
读取json文件为String类型: import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logge ...
- 洛谷 P4779 单源最短路径(标准版) 题解
题面 这道题就是标准的堆优化dijkstra: 注意堆优化的dijkstra在出队时判断vis,而不是在更新时判断vis #include <bits/stdc++.h> using na ...
- 第一课 初识Linux(一)
Linux起源 创始人:李纳斯.托瓦兹 Linux简介: Linux是一套免费使用和自由传播的类UNIX操作系统:是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.Lin ...