ArrayList
ArrayList的继承实现关系图
- ArrayList 底层就是⼀个 Object[] 数组,当实例化ArrayList时没有指定数组容量大小,、第⼀次添加元素(调⽤ add() ⽅法)时会初始化为⼀个⻓度为 10 的数组(即默认初始化容量为 10)
可以创建指定大小的数组,因为ArrayList 容量使⽤完后,会“⾃动”创建容量更⼤的数组,并将原数组中所有元素拷⻉过去,这会导致效率过低,可以使⽤构造⽅法 ArrayList (int capacity) 或 ensureCapacity(int capacity) 提供⼀个初始化容量,避免刚开始就⼀直扩容,造成效率较低
优点:
- 向 ArrayList 末尾添加元素(add() ⽅法)时,效率较⾼
- 查询效率⾼
缺点:
- 扩容会造成效率较低(可以通过指定初始化容量,在⼀定程度上对其进⾏改࠺)
- 另外数组⽆法存储⼤数据量(因为很ᵙ找到⼀块很⼤的连续的内存空间)
- 向 ArrayList 中添加/删除元素(add(int index)),需要移动元素,效率较低
LinkedList
LinkedList继承实现关系图
LinkedList 底层是⼀个双向链表,优点是增/删效率⾼,缺点是查询效率较低。
LinkedList 也有下标,但是内存不⼀定是连续的,LinkedList 可以调⽤ get(int index) ⽅法,返回链表中第 index 个元素 但是,每次查找都要从头结点开始遍历
LinkedList.add ⽅法只能将数据追加到链表的末尾,如果要将对象追加到链表的中间位,则需要使⽤ ListIterator 接⼝的 add ⽅法
ListIterator 中 add ⽅法在调⽤ next 之后,在迭代器左侧添加⼀个元素,调⽤ previous 之后,add 是在迭代器右侧添加元素
总结
LinkedList与ArrayList区别:
相同点:
- 二者都是 List 接口的实现类,具有元素可重复,有序(存取顺序)特点;
- 二者都是线程不安全,效率高;
不同点:
- 数据结构:ArrayList底层数据结构是动态数组,LinkedList底层数据结构是双向链表;
- 随机访问效率:ArrayList 比 LinkedList 在随机访问的时候效率要高,因为 LinkedList 是线性的数据存储方式,所以需要移动指针从前往后依次查找。
- 增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高, 因为 ArrayList 增删操作要影响数组内的其他数据的下标。
综合来说,在需要频繁读取集合中的元素时,更推荐使用 ArrayList,而在插入和删除操作较多时,更推荐使用 LinkedList