先讲讲两者是如何实现的
ArrayList
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
transient Object[] elementData;
private int size;
}
通过源码可以看出,ArrayList实现是基于数组实现的
LinkedList
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
transient int size = 0;
/**
* Pointer to first node.
*/
transient Node<E> first;
/**
* Pointer to last node.
*/
transient Node<E> last;
}
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
}
通过源码可以看出,LinkedList实现是基于双向链表的数据结构。
使用双向链表而不使用单链表是为了能支持反向遍历,快速删除尾部元素
接下来,我们分析下不同操作的情况下,它两的差异
列表头部插入
ArrayList每次头插都需要移动所有元素, 时间复杂度O(n^2)
LinkedList只需要修改指针,时间复杂度O(n)
随机访问
ArrayList直接通过索引计算内存地址,时间复杂度O(1)
LinkedList需要从头节点开始遍历,时间复杂度O(n)
空间复杂度对比
LinkedList比ArrayList多占用数倍的空间,因为LinkedList要多存前后指针等信息
总结
最后留两个问题给大家思考下
//list是linkedlist
for(int i=0; i<list.size(); i++){
System.out.println(list.get(i));
}
for(String s : list){
if(s.equals("bug")){
list.remove(s);
}
}
上述代码有啥问题?