java Collection-ArrayList,
java Collection-ArrayList,
一、ArrayList的概念
1.List是Collection接口的子接口,他的特点是元素有序,并且可以重复,其最常用的类有ArrayList、LinkedList和Vector。
2.ArrayList是list中最常用的方法,是基于数组实现的顺序表,可自动进行扩容,并且直接继承了AbstractList,初始化容量大小是10,当元素要超过容量时,就会重新创建一个更大的数组,并且把原数据复制到新的数组中。
3.ArrayList实现了Serialzable接口,支持序列化,能够根据序列化进行传输。
4.ArrayList实现了RandomAccess接口,支持进行随机访问,也就是能够根据下标序号对数组进行访问。
二、ArrayList中主要的方法
1.ArrayList的初始化只要有三种方法:
(1)当不指定容量大小的情况下,默认初始化的大小为10;
(2)当指定容量大小时,首先会对指定的容量大小进行判断,然后对底层数组elementData进行初始化,大小为指定容量大小;
(3)初始化指定的集合,按照给定的集合对elementData进行赋值,列表元素的大小就是指定的集合的元素的大小,注意:如果指定的集合为空,在初始化的时候回抛出空指针异常
2.ArrayList的扩容方法ensureCapacity(int minCapacity)
(1)如果参数值小于底层数组elementData的长度时,不进行扩容;
(2)如果参数值大于底层数组elementData的长度的1.5倍时,将底层数组的大小扩容到参数值的大小;
(3)如果参数值小于底层数组elementData的长度的1.5倍时,将底层数组的代销扩容到1.5倍;
注意:如果一次扩容太大,会造成空间的浪费,但是如果一次扩容的不够,有可能在对list进行操作时,会频繁的要进行扩容,而扩容操作会对数组进行复制操作,降低程序的运行效率,所以每次扩容的多少是开发人员在时间和空间上做的一个权衡。
3.ArrayList中增加元素的方法
在ArrayList中增加元素主要有四种方法:
(1)add(E e):不增加指定元素的位置,在数组中顺序添加;
(2)add(int index, E e):在指定位置添加元素,这种情况下需要对数组的长度进行判断,避免越界,此时需要对数组进行copy操作;
(3)addAll(Collection c):在数组的末尾增加一个指定的集合中的所有元素,需要对原数组进行copy操作;
(4)addAll(int index, Collection c):在指定的位置插入指定集合中的所有元素,需要对原数组进行copy操作;
在四种添加元素的方法中,在添加元素之前都需要调用ensureCapacity方法,判断是否需要对数组进行扩容,从这几个方法中也可以看出来如果好好的利用ensureCapacity方法,可以对ArrayList的性能进行优化,例如在添加大量元素之前,可以先直接调用ensureCapacity方法进行扩容,减少在插入的过程中进行扩容操作:
4.ArrayList的序列化和反序列化
我们知道序列化主要有两种方式:
(1)只是实现了Serializable接口,序列化时,调用java.io.ObjectOutputStream的defaultWriteObject方法,将对象进行序列化,但是这时候使用transient修饰的字段不会被序列化
(2)实现了Serializable接口,同时提供了writeObject方法,序列化时,会调用该类的writeObject方法,而不是java.io.ObjectOutputStream的defaultWriteObject方法。而这个时候transient修饰的字段是否会被序列化,取决于writeObject的实现方法。
在ArrayList中定义了两个方法writeObject和readObject,来进行序列化和反序列化操作。
在ArrayList中对elementata的定义是transient的,因此在对ArrayList进行序列化时,默认是不会对elementData进行操作的,这是因为elementData相当于是一个动态数组,每次在占满容量之后就会进行自动扩容,而假如不定义为transient类型时,当数组的大小特别大,而其中只存放了很少的元素,那么序列化就会生成很多的null元素。
如果ArrayList实现了writeObject和readObject方法,那么在序列化和反序列化的时候就可以按照自定义的方法来执行动作,每次在序列化的时候先调用defaultWriteObject方法对非transient元素进行序列化,然后去便利elementData,对其中存在的元素进行序列化,同样使用相同的方法进行反序列化。
这种做法主要是加快了序列化的速度,同时也减少了序列化之后文件的大小。
三、ArrayList中主要方法涉及的操作
ensureCapacity(扩容检查) | copy(复制元素) | rangeCheck(边界检查) | |
add(E e) | Y | N | N |
add(int index, E e) | Y | Y | Y |
get(int index) | N | N | Y |
set(int index, E e) | N | N | N |
remove(int index) | N | Y | Y |
remove(Object o) | N | Y | Y |
addAll(Collection c) | Y | Y | N |
addAll(int index, Collection c) | Y | Y | N |
removeRange(int fromIndex, int endIndex) | N | Y | N |
四、ArrayList的优缺点
1.底层是以数组的形式实现,加上实现了RandomAccess接口,在进行get操作的时候非常快;
2.在顺序添加元素的时候非常方便,只需要在数组中添加一个元素即可;
3.在根据下标插入元素或者删除元素的时候,都涉及到对原数组的复制操作,如果要复制的元素非常多,会影响性能;
4.比较适用于顺序添加,随机访问的场景
相关文章
- 暂无相关文章
用户点评