先讲讲两者是如何实现的
ArrayList
java">public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{transient Object[] elementData; private int size;
}
通过源码可以看出,ArrayList实现是基于数组实现的
LinkedList
java">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要多存前后指针等信息
总结
最后留两个问题给大家思考下
java">//list是linkedlist
for(int i=0; i<list.size(); i++){System.out.println(list.get(i));
}
java">for(String s : list){if(s.equals("bug")){list.remove(s);}
}
上述代码有啥问题?