21_List 集合接口实现类对比
1、List 集合
1.1 List 集合概述
List 集合特征:
1、有序
2、可重复
List 集合实现类
1、ArrayList
底层结构是可变长数组结构
特征:增删慢、查询快
2、LinkedList
底层结构是带有链表头的双向链表结构
特征:增删快、查询慢
3、Vector
线程安全、性能较低,底层结构为可变长数组结构
1.2 ArrayList 实现类
1.2.1 ArrayList 概述
底层是一个可变长数组结构,数组数据类型为 Object 类型,可以存储任意类型元素,通过所有可以给予当前数组进行数据添加操作的方法(add,
addAll, set) 限制泛型类型,同时集合中所有可以获取底层数组元素的方法也引入泛型约束(get,subList),保证集合存储数据类型一致化和集合数据
获取类型一致化。
底层数组扩容 grow 方法操作由 ArrayList 自行完成,
扩容的流程:
1. 方法参数为最小容量需求 minCapacity = size + 添加元素个数;
2. 获取原数组容量 oldCapacity
3. 计算得到新数组容量
newCapacity = oldCapacity + oldCapacity / 2;
newCapacity = oldCapacity + (oldCapacity >> 1);
数据右移一位 (oldCapacity >> 1) <===> oldCapacity / 2
4. 判断新数组容量是否满足最小容量要求
5. 判断新数组容量是否超出 MAX_ARRAY_SIZE
6. 创建新数组
7. 从原数组中移动数据到新数组
8. 存储新数组地址
1.2.2 ArrayList 增删慢
增加慢:
1. 增加操作有可能会导致数组容量扩容,扩容操作中,数据从原数组移动到新数组【时间效率低】
【空间效率低】因为在扩容操作过程中,方法运行所需内存空间是 原数组的 2.5 左右(1 + 1.5),数据空间占用较高,同时在执行数据复制移动操作之后,
原数组数据空间需要收回
2. 在指定下标位置添加元素,只要不是采用【尾插法】,从添加数据位置开始,之后元素需要整体向后移动,移动过程【时间效率低】
删除慢:
1. 指定元素删除操作,除末尾元素删除,其他任意一个位置元素删除之后,从删除位置开始所有数组元素整体向前移动。移动过程非常浪费时间【时间效率低】
2. 删除操作,有可能会导致有效数据和数组底层容量【比例失衡】,以及空置的元素空间个数超过【阈值】
3. 一旦触发缩容操作,同样会导致
【时间效率低】数据需要移动
【空间效率低】在缩容的过程中,方法执行过程空间占用较大,包括对于原数组空间释放需要时间
1.2.3 ArrayList 查询快
ArrayList 底层是一个 Object 类型,同时有下标操作的方式,可以根据数组首地址 + 下标快速计算对应元素所在的内存地址,CPU 快速访问,效率极高。
1.3 LinkedList 双向链表结构
1.3.1 LinkedList 概述
带有链表头的双向链表结构 整个链表结构有两个数据类型
1、链表头 LinkedList<E>
2、结点 Node<E>
class LinkedList<E> {
Node<E> first; //链表头节点
Node<E> last; //链表尾节点
int size; //链表中 Node 结点的个数
}
class Node<E> {
Node<E> prev; //上一个结点
E e; //存储元素内容
Node<E> next; //下一个结点
}
1.3.2 LinkedList 集合特征方法
1、addFirst(E e);
在链表头添加符合实例化过程泛型约束元素
2、addLast(E e);
在链表尾添加符合实例化过程泛型约束元素
3、E getFirst();
获取链表头结点存储元素
4、E getLast();
获取链表尾结点存储元素
5、E removeFirst();
删除链表头结点,返回值是删除的元素
6、E removeLast();
删除链表尾结点,返回值是删除的元素
import java.util.LinkedList;
public class Demo1 {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
System.out.println(list);
System.out.println("____________________");
list.addFirst("AAA");
System.out.println(list);
System.out.println("____________________");
list.addLast("ZZZ");
System.out.println(list);
System.out.println("____________________");
System.out.println(list.getFirst());
System.out.println(list.getLast());
System.out.println("____________________");
System.out.println(list.removeFirst());
System.out.println(list.removeLast());
System.out.println(list);
System.out.println("____________________");
}
}