这篇博客来介绍一下List接口:
这个接口继承自Collection接口,具有一定的关联关系,这里的List就是特指线性表这类的数据结构,它典型的实现就是ArrayList,Vector,LinkedList,在前面的三篇博客中介绍了关于我们自己创建链表和顺序表的操作,
接下来我们就看一下有关List接口的基本操作:
1.实例化一个接口
与之前的Collection接口类似,这里的List也是一个接口,不能直接new List.
关于这行代码,实际上进行了向上转型,实际new的是ArrayList,使用List类型的引用来保存了这个对象.
List<String> list=new ArrayList<>();
2.新增元素
list.add("C语言");
list.add("C++");
list.add("Java");
list.add("Python");
list.add("PHP");
3.打印整个list
我们知道如果System.out.println();这个方法中的参数如果是引用类型的时候,会调用obj.toString,源码如下:
而我们的集合类中都重写了toString方法,所以可以直接进行打印.
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
System.out.println(list);
4.使用下标访问
如果当前是ArrayList ,get/set按下标访问的方式,是比较高效的(时间复杂度是O(1))
如果当前List是LinkedList,get/set按下标访问比较低效,时间复杂度是O(N),链表更擅长插入
System.out.println(list.get(0));
list.set(0,"Go");
System.out.println(list);
5.截取部分内容包含1 不包含3
System.out.println(list.subList(1,3));
6.重新构造一个List 这里的构造是浅拷贝
List<String> arrayList=new ArrayList<>(list);
List<String> LinkedList=new LinkedList<>(list);
System.out.println(arrayList);
System.out.println(LinkedList);
7.基于现有List的引用进行强制转换(向下转型)
向下转型的前提是发生过同种类型的向上转型.
ArrayList<String> arrayList1=(ArrayList<String>) list;
//不能强转成链表
LinkedList<String> LinkedList1=(LinkedList<String>) list;
我们也要注意一下,虽然链表和顺序表都实现了List接口,也就是说ArrayList和LinkedList都支持List中的操作,但是还是有一些区别的,就像get和set方法,如果是ArrayList随机访问就比LinkedList效率高,在构造方法上与LinkedList不同的ArrayList(指定顺序表初始容量),有这样的构造方法
接下来我在线性表这里以ArrayList和Vector的区别来结尾:
- 1.ArrayList底层结构是顺序表(基于数组);LinkedList链表
- 2.ArrayList数据存放在连续的内存空间上,LinkedList不是存放在连续的内存空间上的
- 3.ArrayList能够高效的进行"随机访问",按照下标操作元素的时间复杂度是O(1),
由于内存具有随机访问能力,那么CPU访问不同的地址差异不大,成本不大,内存能够随机访问,数组才能随机访问,ArrayList基于数组的结构才能随机访问 - 4.LinkedList能够高效的进行插入删除O(1) ,由于LinkedList的指定位置插入add方法也是通过下标来确定位置,取下标操作仍然是O(N),对于add(index,elem)如果是ArrayList,取下标过程是O(1),插入过程是O(N),如果是LinkedList,取下标过程是O(N),插入过程是O(1)
- 5.ArrayList在初始化的时候可以通过capacity参数指定最大容量,当add尾插的时候,如果元素个数小于capacity,效率都很高O(1),如果达到capacity,此时就会触发扩容操作(一般重新new一个更大的(1.5倍)连续内存空间,把原来的元素搬运过来,再释放旧空间)
LinkedList就没有capacity这个概念,每次新插入一个元素,就去new一个特定的节点对象(如果ArrayList没有达到扩容时,插入效率可能会比LinkedList高) - 6.在频繁内存申请和释放的时候就容易产生操作系统的内存碎片,很难找到一块足够大的连续内存空间ArrayList比较害怕内存碎片,LinkedList则不害怕
tips:解决内存碎片:JVM 释放内存=>复制算法,效率比较低.
至此关于List接口,顺序表及链表这两种数据结构的介绍就告一段落~