List是Collection的子接口,采用泛型,其中下面是List对Collection的补充方法:
注意方法重载。
那么如何使用呢?我们需要实现类。常用的有:
ArrayList(95%),Vector(4%)【ArrayList的早期实现】,LinkedList(1%)
其中前两个是基于动态数组扩容的思想完成(新数组覆盖老数组),第三个是双端(双向)链表,可以用它模拟堆栈和队列的数据结构;需要注意的是ArrayList线程不安全,Vector线程安全。
还需要注意List中的接口和Collection都有remove方法,但不是重写,是重载,方法参数类型不一样。
实现类
ArrayList
它的父是AbstractList <E>,然后才是List<E>
使用的是数组结构,增加删除慢,查找,修改快。使用泛型Object数组存储数据。
注意:
1.请务必确认初始容量,否则不断频繁扩容,浪费资源,效率下降
2.扩容大小为之前的1.5倍
3.默认大小为10,但刚创建长度为0
4.添加add方法永远返回true,无论是否添加成功
5.只有第一次添加时,才会把长度设为10
以下为自己测试代码和笔记:
//arraylist是数组结构,增删慢,查找快
//如果存储初始的容量比较大,建议指定大小,否则频繁扩容,浪费资源,扩容大小为原来的1.5倍
//默认大小为10,但是刚创建长度0
ArrayList<Integer> list = new ArrayList<>();
//返回永远为true
//只有第一次添加,才会把长度设为10
list.add(1);
//向指定位置添加,index=0;element=10;
list.add(0, 10);
System.out.println(list.get(0));
}
源码部分
初始化,并未添加:
添加方法返回true源码:
扩容1.5倍:
其中第二红圈下面return就是第一次add时进入的路径。
简单理解就是原长度右移一位(除2),再加上旧长度就是1.5倍增加。下面还有个hugeLength方法,她是用来判断是否溢出,以及是否在int最大值-8的区间内。
Vector
基本用法和arrayList一致,就是扩容是双倍扩容,先基本不用,她是线程安全的,但效率不高,对应现在web高并发使用率不高,且是ArrayList的早期实现版本。
其中有一个方法:
//返回当前容量,非使用量
System.out.println(vector.capacity());
返回的是当前总容量,包含没有使用的部分。
LinkedList
她是双向链表结构,增删快,查找慢。基于该结构的特性我们可以模拟栈,单端队列,双端队列。
具体请看下面的代码。
练习部分代码:
LinkedList<Integer> list = new LinkedList<>();
//首部添加
list.addFirst(1);
list.addFirst(2);
list.addFirst(3);
//它在首部,往下压
list.addFirst(4);
//尾部取,也可以首部取
System.out.println("得到的底部:"+list.getLast());
//首部取
System.out.println("得到的顶部:"+list.getFirst());
//移除最后一个
Integer num = list.removeLast();
System.out.println("移除的最后一个:"+num);
//压栈
list.push(10);
list.push(20);
list.push(30);
//弹栈
Integer i = list.pop();
System.out.println("栈顶元素为:"+i);
三者区别
相同点:他们都是实现了List接口,都是线程不安全的;
不同点:ArrayList底层实现时数组,数组有下标,所以他的改查功能速度要快一点,而LiekedList 的底层实现是链表,他的增删速度要快一点。
集合名称 | 数据结构 | 查询速度 | 增删速度 | 线程安全性 | 效率 |
---|---|---|---|---|---|
ArrayList | 数组 | 快 | 慢 | 不安全 | 高 |
LinkedList | 链表 | 慢 | 快 | 不安全 | 高 |
Vector | 数组 | 快 | 慢 | 安全 | 低 |
后续如有需要在补充。
下次见,sue。
2021年3月1日15:16:52