在循环arrayLlist时,经常会遇到remove操作,那么arrayList的remove的底层是怎么做的?
AbstractList中,有一个属性modCount,这个属性是跟踪list中数据被修改的次数,任何对list的add/remove操作,都将导致modCount++.
在AbstractList中还有一个内部类Itr implements Iterator,Itr是一个list遍历的工具类,当然list.iterator()方法也是返回Itr对象,在Itr中有一个校验位属性expectedModCount;对于一个itr对象,其初始时expectedModCount=modCount.
Iterator是list一个视图,其最终还是操作list的存储结构.在使用iterator遍历时,remove()操作,会导致modCount++(AbstractList.remove()),但是还有expectedModCount=modCount,即在iterator中remove数据,会带来expectedModCount与modCount值的同步.
在Iterator遍历时,next(),remove()方法会校验expectedModCount与modCount值是否一致,如果不一致,就意味着这list数据在iterator外部被修改,此时iterator遍历将会造成ConcurrentModificationException.
AbstractLlist不仅支持普通的iterator,还支持ListIterator(ArrayList,LinkedList均支持),ListIterator增加了遍历时双向游标能力(previous,next),增加了add方法.add方法和remove方法一样也做了expectedModCount和modCount一致性校验.
引申一下,如下四个对list数据删除的代码,有区别吗??
如下是4中循环方式:
1) for(int i=0;i<list.size();i++){
list.remove(i);
}
2) for(int i=list.size()-1;i>=0;i--){
list.remove(i);
}
3)
int size = list.size();
for(int i=size-1;i>-1;i--){
list.remove(i);
}
4) for(Object i : list){
list.remove(i);//如果list中存在多个Object互相equals时,此方法仍然有效.注意list.remove(Object)内部使用了遍历操作,并使用equals来比较对象并删除.
}
5) Iterator it = list.iterator()
while(it.hasNext()){
it.next();
it.remove();
}
1),2),3)是最普通的遍历方式,但是在遍历并有删除操作时,似乎它们执行的结果还有些差距,根据坐标删除,那么1)实事上只会有一半被删掉,1)中每删除一次,计算一次list.size(),但是当前i++,且前端删除会造成数组结构copy.
2)后端删除,不会造成copy,每次都是删除最后一个位置,直至结束
3)因为size没有重新计算,在删除一半数据后,抛出IndexOutOfBoundsException
4)/5)正常
提示:foreach方式最终是转换成了iterator的方式进行.(产生于编译过程中).
相关推荐
### ArrayList数据批量添加数据 #### 知识点概述 在.NET框架中,`ArrayList`类是一种动态数组,用于存储不同类型的数据。本篇文章将详细介绍如何利用`ArrayList`进行数据的批量添加,并通过一个示例来展示如何在一...
ArrayList动态删除与自定义Adapter是Android开发中的常见操作,它涉及到数据存储、用户界面更新以及适配器模式的运用。在Android中,ListView是展示大量数据的常用组件,而ArrayList作为Java集合框架的一部分,通常...
C#中有多种数据结构可以用来存储和管理数据,今天我们将讨论四种常用的数据结构:Array、ArrayList、Hashtable和Dictionary。这些数据结构都是_Collections_命名空间的一部分,提供了不同的方式来存储和检索数据。 ...
为了将ArrayList中的数据填充到DataGrid,我们需要创建一个DataTable并映射到ArrayList中的对象,因为DataGrid默认使用DataTable作为数据源: ```csharp DataTable dataTable = new DataTable(); dataTable.Columns...
在这个主题中,我们将深入探讨如何在JNI中操作ArrayList对象并添加一个int类型的数据。 首先,我们需要理解ArrayList在Java中的本质。ArrayList是Java集合框架中的一个重要类,它实现了List接口,用于存储可变大小...
在C#编程语言中,数组和ArrayList是两种不同的数据结构,它们各自有着特定的用途和特点。本篇文章将深入探讨这两种数据结构,以及它们在实际编程中的应用与区别。 首先,数组是C#中最基本的数据结构之一,它是一种...
本主题将深入探讨如何在Android应用中动态地添加和删除Spinner菜单,以及ArrayList和Widget之间的依赖关系。 一、Spinner的基础知识 Spinner是Android SDK中的一个视图组件,继承自AdapterView,它可以通过一个...
在Java编程语言中,ArrayList和LinkedList都是集合框架中两种重要的数据结构,它们分别基于不同的底层实现,具有不同的特性和性能特点。以下是对这两个类的详细分析: 1. **ArrayList 实现**: - ArrayList 实现了...
在Java编程语言中,数据结构是组织和存储数据的关键元素,它们提供了高效访问和操作数据的方式。本主题将深入探讨ArrayList、Stack和Map这三种重要数据结构,它们各自具有独特的特性和用途。 **ArrayList** 是Java...
ASP.NET中的ArrayList对象是.NET框架中System.Collections命名空间下的一个类,它提供了一个动态大小的数组,用于存储各种类型的数据。ArrayList对象是一个非常基础且灵活的集合类,它允许程序员在运行时添加、删除...
C# ArrayList是一个重要的数据结构,它是.NET框架早期版本中用于动态数组存储的类。这个类在System.Collections命名空间中,提供了灵活的大小调整和数据管理功能。ArrayList在C#编程中扮演了重要的角色,尤其在处理...
C#中的数组和ArrayList都是常见的数据存储方式,但它们有着不同的特性和应用场景。本篇主要探讨C#数组和ArrayList在游戏开发中的高级使用技巧。 首先,数组是C#中最基础的数据结构之一。它是一个存储相同类型元素的...
在这个场景中,我们将探讨如何利用ArrayList来实现ListView,以及如何添加编辑、新增、删除功能,以及在Activity间传递参数,同时还会涉及到ContextMenu和OptionsMenu的实现,以及长按事件的处理。 首先,我们需要...
在实际编程中,根据需求选择合适的数据结构,比如如果频繁进行插入和删除操作,考虑使用LinkedList;如果需要快速访问且元素数量相对固定,ArrayList可能是更好的选择。在分析代码性能时,也应考虑到ArrayList的内部...
1. **结构体定义**:C语言中没有类的概念,所以`ArrayList`会通过结构体来封装数据。结构体通常会包含一个元素数组、数组的当前容量以及实际元素的数量。 ```c typedef struct ArrayList { void **elements; // ...
首先,ArrayList 和 Vector 都是采用数组方式存储数据的,这种方式可以快速地索引数据,但是插入数据需要移动数组元素,性能较慢。Vector 由于使用了 synchronized 方法,因此具有线程安全性,但是这也使得其性能比 ...
在编程领域,尤其是在C#语言中,数组和ArrayList是两种常用的数据存储结构。它们各自有其特点和适用场景,理解并熟练运用它们是提升编程能力的关键。本文将深入探讨数组和ArrayList,帮助你掌握这两种数据结构的核心...