栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

Java列表和队列用法与原理剖析(1.ArrayLIst)

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java列表和队列用法与原理剖析(1.ArrayLIst)

本文是阅读《Java编程的逻辑》进行的学习笔记总结,如有错误望各位指正

ArrayList 用法

ArrayList是一个动态数组泛型容器,新建ArrayList需要实例化泛型参数,如:

ArrayList al = new ArrayList();

同时写有增删改查的各种方法,在这里就不一一解释了

原理

ArrayList内部有一个数组elementData和一个整数size,ArrayList的各种public方法内部操作都是基于这个数组和这个整数,elementData会随着实际元素个数的增多而重新分配,而size始终记录实际元素的个数,要注意的是,类似于add,remove这些方法都会用modCount来记录内部的修改次数,要记录修改次数的原因,下面的[迭代的陷阱中]解释

迭代

ArrayList实现了Iterable接口,所以支持foreach语法。
Iterable接口里面实现了iterator()方法,iterator()方法返回的是一个Iterator对象,实际就是使用Iterator接口的方法进行遍历。也就是说

  • 对象只要实现了Iterable,就可以使用foreach
  • 类可以不用实现Iterable,也能创建Iterator对象
迭代的陷阱(小心,也是用foreach删除元素报错的原因)

如果想用迭代的方式删除小于100的元素,直觉上可以这么写

public void remove(ArrayListlist){
	for(Integer a:list){
		if(a<=100){
			list.remove(a);
		}	
	}
}

但运行时会抛出异常:ConcurrentModificationException并发修改异常,这是因为迭代器内部会维护一些索引位置相关的数据,要求在迭代过程中,容器不能发生结构性变化,否则这些索引位置就失效了。所谓结构性变化就是添加,插入,删除操作,修改内容不算结构性变化。而之前所说的modCount记录内部修改次数就是为了迭代器判断是否发生结构性变化设置的。
如果想要避免异常,可以使用迭代器的remove方法,如下:

public static void remove(ArrayList list){
	Iterator it = list.iterator();
	while(it.hasNext()){
		if(it.next<100){
			it.remove();
		}
	}
}

迭代器是如何知道发生了结构性变化的呢?

ArrayList中iterator方法,会新建一个实现了Iterator接口的Itr对象,这个对象内部有三个int类型的成员变量cursor(表示下一个要返回元素的位置),lastRet(表示最后一个返回的索引位置,没有则为-1),expectedModCount(表示期望的修改次数,初始化为modCount),上一节也说过,modCount是用来记录内部修改次数的,而每次迭代器操作的时候都会检查expectedModCount是否等于modCount,这样就可以检测出结构性变化。
而迭代器的remove方法能够成功,是因为它remove的同时更新了cursor、lastRet、expectedModCount的值,所以可以正确删除,在这就不具体说明,详情可看其源码。

ArrayList实现的主要接口
  1. Collection
    Collection表示一个数据的集合,数据间没有位置或顺序的概念
  2. List
    List表示有顺序或位置的数据集合,它扩展了Collection。增加了一些关于位置的方法
  3. RandomAccess
    这个接口没有定义任何代码,这种称为标记接口,用于声明类的一种属性
    实现了RandomAccess接口的类表示可以随机访问,随机访问的意思是类似于数组那样,数据在内存中是连续存放的,根据索引值就可以直接定位到具体的元素,访问效率很高,你可以随机访问任一个节点,而不需要通过当前节点查找后续节点,遍历访问模式请参考LinkedList的结构。
小tips:ArrayList打印顺序会与添加顺序一致

ArrayList使用线性顺序存储结构,和数组一致,每个对象有一个index,index本身是有序的,所以你添加的时候,index有序增长,遍历的时候,按照index遍历,也是有序的。存放和访问顺序可能不一致,那需要在存放的时候就是随机存放的,比如HashMap,数据通过hash计算后无序存放,所以获取的时候也是随机的,需要存放和读取顺序一致,就要包装一层LinkedList,也就是LinkedHashMap

ArrayList特点分析

ArrayList特点是内部采用动态数组实现,有以下特点

  1. 可以随机访问,按照索引位置访问效率很高,O(1)
  2. 按照内容查找元素效率较低,O(N)
  3. 添加元素效率一般,重新分配和复制数组的开销被平摊了,O(N)
  4. 插入和删除元素效率较低,因为需要移动元素,O(N)
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/984737.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号