2016-9-6 ~ 2016-9-8 深入了解 java.util.Collection
本文仅记录 ArrayList & LinkedList 的个人理解
- Collection<E> (interface)implements Iterator<E>
-List<E> (interface) implements Collection<E>
- ArrayList implements List<E>
- LinkedList implements List<E>
大概上,ArrayList 和 LinkedList 都是属于 List 的实现,两者作为最常用的java 集合之一,在一定程度上具有一些相同的属性(都是基于Array数组的方式实现存储对象);按用途分析其实两者之间有很多不同的特性,由于不同的特性,我们在使用的时候应该根据两者不同的设计用途判断在哪种环境下使用。两者的区别可以从设计结构上看出:
椭圆: interface
圆角矩形: abstract class
矩形:class
结构上的设计明显可以看出两者的不同用途,实现过程中 LinkedList 是比 ArrayList 要复杂,用途也比 ArrayList 要多。
- ArrayList
1. ArrayList 实现了 List<E> 接口,内部的对象存储主体是Object[ ] elementData ,容量默认大小为10;
2. ArrayList 提供了三种方式创建实例,在使用的时候最好能够按照需求平衡定义所需的 ArrayList 容量;
3. ArrayList.ensureCapacityInternal(int minCapacity) 用于确认容量是否满足需求,若不满足则调用 grow(minCapacity)扩充容量
4. grow() 方法中会将容量扩充到旧容量的1.5倍:
int newCapacity = oldCapacity + (oldCapacity >> 1);
5. 并且扩充容量后调用 Array.copyOf() 方法复制 Old_elementData[] 到 New_elementData[]这在运行时的消耗系统空间,降低运行效率。
6. ArrayList 的存储由数组实现,所以其存储列表也继承了数组有序的特性。
7. ArrayList.get( ) 由于单纯由数组对象存储,可以快速的定位目标对象。
8. ArrayList.add( ) 提供两种添加方法,一种是直接在尾部添加新对象,另一种在指定坐标插入新对象;
明显,作为数组存储对象,频繁的插入删除操作将意味着需要消耗空间去修改数组对象的位置,效率低;
9. ArrayList.iterator() 迭代器有两个,一个由内部类 Itr 实现,该内部类实现了 iterator<E> 接口
10. ArrayList.listIterator() 由内部类 ListItr 实现,该内部类 ListIter extend Itr implements ListIterator<E>
- LinkedList
1. LinkedList 实现了 List<E> 接口,内部的对象存储主体是其内部类 Note<E>一个一个节点构成;
2. 所有对 LinkedList 的操作最终都将转化为 对Note<E>的逻辑操作。
3. 实现 LinkedList 的主要逻辑方法有 6 个:
(1) pirvate void linkFirst(E e) -- 在链表头插入新节点
(2) void linkLast(E e) -- 在链表尾插入新节点
(3) void linkBefore(E e, Node<E> succ) -- 在链表内指定节点 succ 前面插入新节点 e
(4) private E unLinkFirst(Node<E> f) -- 在链表头删除一个节点
(5) private E unLinkLast(Node<E> l) -- 在链表尾删除一个节点
(6) E unLink(Node<E> x) -- 删除指定节点
4. 根据下标查找一个节点 node(E e);使用折半查找
5. LinkedList 的迭代器有三种,listIterator(int index)iterator() listIterator()
#listIterator(int index)由 LinkedList 内部类 ListItr 实现.
# 后两种结构实现比前一种复杂:
6. LinkedList 的列表构造主要靠的是 Note<E> 每一个节点中的 prev,next 指向从而形成链表,所以插入删 除性能较好
7. LinkedList 的列表查询使用折半查找,但是需要由各个节点与目标节点对比以找出目标,效率较差
8. LinkedList 提供 peek() poll() 方法用于实现队列
9. LinkedList 提供 posh() pop() 方法用于实现堆栈
10. LinkedList 还提供了 offerFirst() offerLast() 等方法用于实现双端队列
-- 两者比较:
从两者的各个功能和实现方式上看,ArrayList 在明确容量,插入删除少的情况性能较 LinkedList 要好,毕竟数组简单轻便,能够实现快速的随机访问,主要用于读;而 LinkedList 则趋向于实现复杂的算法结构,能够承受频繁的插入删除操作,但是查找效率不高,主要用于写。