从两个方面进行比较,内容并不很全面,目的主要还是形成一个整体印象
- 各自主要特性
- 各自常用的操作及对应的时间复杂度
一、主要特性
ArrayList:非线程安全,可调整大小,可保持加入的顺序,因为底层存储结构是数组,按照数组下标进行添加。扩容机制已总结过,不再赘述
LinkedList: 非线程安全,底层是双向链表
1.ArrayList的存储结构,是Object数组
transient Object[] elementData; //
// 在其中发现了一个没留意过的迭代器,是基于索引的、懒初始化的二分迭代器,这是Java 1.8才引入的,看了下注释,大概用途是将数组、集合、
// IOchannel 或者构造函数分割进行处理,有点抽象的一个功能,暂不深究
static final class ArrayListSpliterator<E> implements Spliterator<E>
2.LinkedList的存储结构是链表,保存两个节点,然后通过节点进行查找。节点是LinkedList的静态内部类实现
transient Node<E> first;
transient Node<E> last;
// 静态内部类
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
二、常用的操作方法
1.ArrayList:
// 返回元素个数 时间复杂度:O(1)
public int size()
// 添加元素 时间复杂度:O(1)
public boolean add(E e)
public void add(int index, E element)
// 移除元素 时间复杂度:O(1)
public E remove(int index)
// 合并集合,将c转成数组,再调System.arrayCopy 进行合并
public boolean addAll(Collection<? extends E> c)
// 检查是否包含某元素,通过遍历的方式 时间复杂度:O(n)
public boolean contains(Object o)
// 排序,底层使用折半插入排序算法(**待补习**)
public void sort(Comparator<? super E> c)
- LinkedList:
// 返回头,但不移除元素
public E peek()
//返回头,并移除元素
public E poll()
// 遍历链表,所以时间复杂度是O(n)
public int indexOf(Object o)
//同理,此方法也是通过遍历,才找到对应下标的元素
Node<E> node(int index)
// 在队列两端插入
public void addFirst(E e)
public void addLast(E e)
// 在队列两端移除
public E removeFirst()
public E removeLast()
小结:
1.ArrayList是平时很常用的集合,使用时主要注意多线程下的处理,以及在某些情况下,初始容量的设置,以减少扩容的次数,提高使用性能
2.LinkedList目前个人工作中使用不多,遇到具体情况可具体分析