常用集合ArrayList浅度解析(博客园迁移)
来源:互联网 发布:伊特进销存软件 编辑:程序博客网 时间:2024/05/17 01:46
首先,先看一下java中对ArrayList的定义代码:
public
class
ArrayList<E>
extends
AbstractList<E>
implements
List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private
static
final
long
serialVersionUID = 8683452581122892189L;
/**
* Default initial capacity.
*/
private
static
final
int
DEFAULT_CAPACITY =
10
;
/**
* Shared empty array instance used for empty instances.
*/
private
static
final
Object[] EMPTY_ELEMENTDATA = {};
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == EMPTY_ELEMENTDATA will be expanded to
* DEFAULT_CAPACITY when the first element is added.
*/
private
transient
Object[] elementData;
这段代码能给我们提供的信息:
第一:ArrayList实现了RandomAccess接口,因此查询会很快
第二:ArrayList实现了序列化和Cloneable接口,讲道理应该可以进行克隆操作,但是这里有争议说不是,因为这样操作是同一个对象,不过我自己测试不是一个对象。存在争议点。。。
第三:ArrayList底层使用数组实现,这个数组默认的长度是10.
好了,从上面的代码似乎只能得到这些结论。但是既然是ArrayList,一定是长度可以增加的,这样推理的话,数组肯定是可变的,倘若再沿着Arraylist的定义文件代码往下看,确实是这么回事。但既然是浅度解析,就不一一分析全部代码了,结论就是ArrayList底层用一个可变数组进行对元素的存放,这个数组初始长度是10,而且根据情况可以进行扩容。
对于扩容,我们会关心的一个问题是:每次扩多大啊?倘若一次扩容太大,就会造成空间浪费啊,如果扩的不够,就会频繁出现扩容操作,也是会消耗性能。对于这个问题,设计者为我们选取一个折中的大小,倘若原来大小的size表示,扩容后的大小为:size*3/2+1。
然后说说ArrayList扩容用的底层,就是数组的拷贝:Arrays.copyOf(array0,newSize);基于数组的拷贝,ArrayList的删除元素的操作流程可以分为以下三个步骤:
①删除数组指定位置的元素。②将后面所有元素进行数组拷贝操作向前移动一个位置。③最后一个元素置为null,让垃圾回收机制进行回收空间。
数组添加元素跟删除道理差不多。基于这个情况,我们可以得出ArrayList的两个缺点:
1、删除元素的时候,涉及到一次元素复制,如果要复制的元素很多,那么就会比较耗费性能
1、ArrayList底层以数组实现,是一种随机访问模式,再加上它实现了RandomAccess接口,因此查找也就是get的时候非常快
2、ArrayList在顺序添加一个元素的时候非常方便,只是往数组里面添加了一个元素而已
所以说ArrayList适合顺序添加,随机访问,而像LinkedList则适合插入删除等较多的集合操作。只能说大多情况,针对特定的效率也不尽然,因为是数组拷贝操作,ArrayList对于较靠后的元素的删除和添加操作速度反而会比LinkedList快很多呢。
最后写点备忘的技巧:
①ArrayList是线程不安全的,如果非需要线程安全的话,可以使用Collections.synchronizedList来,操作如下:
List<String> list= Collections.synchronizedList(list);
list.add(
"aaa"
);
list.add(
"bbb"
);
for
(
int
i =
0
; i < list.size(); i++)
{
System.out.println(list.get(i));
}
②对于集合操作,如果实现了RandomAccess接口(如ArrayList),尽量使用for(int i=0;i<size();i++)这种方式进行遍历,比增强的for循环效率快一倍。而没实现RandomAccess的(如linkedList),如果使用普通的for循环比使用迭代器效率低上千倍。所以:
if
(list instance of RandomAccess) {
for
(
int
m =
0
; m < list.size(); m++){}
}
else
{
Iterator iter = list.iterator();
while
(iter.hasNext()){}
}
)
- 常用集合ArrayList浅度解析(博客园迁移)
- ArrayList集合源码解析
- 源码解析-集合-ArrayList
- 常用集合※【ArrayList】
- Java集合源码解析(一)ArrayList源码解析
- java几种集合遍历速度对比(博客园迁移)
- Java集合源码解析-ArrayList
- Java集合ArrayList源码解析
- java集合之ArrayList解析
- 【Java集合类】ArrayList解析
- Java ArrayList集合常用方法
- Java集合 -- ArrayList常用方法
- 一步一步解析集合框架ArrayList源码(2)
- 一步一步解析集合框架ArrayList源码(3)
- 一步一步解析集合框架ArrayList源码(4)
- Java集合框架--ArrayList源码解析(JDK1.7)
- 博客迁移->>>>>>博客园-Jackson0714
- 博客迁移至博客园
- Java中CAS详解
- order by 语句对null字段的默认排序
- 再探Fork之孤儿进程与僵尸进程
- 一、百度2017春招 <买帽子>
- Windows7搭建Apache本地服务器+PHP环境
- 常用集合ArrayList浅度解析(博客园迁移)
- springBoot 由jar包转换为war包
- SSh整合
- JAVA设计模式之享元模式
- Android所有的颜色
- Matlab自带的分类学习工具箱(SVM、决策树、Knn等分类器)
- 修改CentOS下的网络接口名称
- 类和对象 -----继承
- React-navigation导航系统(3)-高级指南