java集合Collection的List ArrayList LinkedList 区别

时间:2021-08-04 19:22:25

先说结论:

1、List的特点:线性顺序存储元素、元素可重复、可以存放null、可查找。

2、ArrayList(数组,中间插入删除、按位置查找)、LinkedList(链表,中间插入删除、按位置查找

 

==============正文============

一、List特点

    如下图所示List表示一种列表的形式,因此它的元素都是一个接一个的线性排序,所以它可以重复,也可以存null

java集合Collection的List ArrayList LinkedList 区别

二、关于List的方法

    List的方法这里就不逐一介绍了,讲一些我认为大家平时可能会忽略的方法。

第一个方法:List<E> subList(int fromIndex, int toIndex),先熟悉一下下面的代码:

    @Test
    public void testsubList(){
        List<String> list = new LinkedList<>();
        list.add("list0");
        list.add("list1");
        list.add("list3");
        list.add("list2");

        List<String> strings = list.subList(1, 3);
        strings.remove(0);

        strings.forEach(System.out::println);
        System.out.println("-----------");
        list.forEach(System.out::println);

//        ClassCastException 不能转型 返回的私有内部类SubList
//        ArrayList<String> strings2 = (ArrayList<String>) list.subList(1, 3);
//        LinkedList<String> strings2 = (LinkedList<String>) list.subList(1, 3);
    }

    首先我们说一下注释的部分,注释中subList返回的对象是不能转型的,它实际上是一个ArrayList私有的内部类SubList所以不能转型(注:LinkedList没有自己实现,继承AbstractList的实现,有一个维嘉什么修饰符的SubList累)。

    下面是这段代码打印的结果,我们在代码里没有删除list对象中的list1,但是打印的结果显示也是被删除了的。所以这里subList返回的对象实际上相当于原来list对象的一个视图,对于subList返回对象的所有操作最终都会映射到原对象中去。(注:其实查看原来你就可以发现subList方法并没有创建新对象来克隆当前对象,它只不过在SubList私有类中保存了当前对象的引用,同时限制了访问原有对象的中整个集合的范围而已)

list3
-----------
list0
list3
list2

    方法暂时就介绍到这里,需要提一下的是关于listIterator我放到迭代器里面去一起讨论。

    注意:在Collection中是没有定义类似于get这样的查找集合中元素的方法,但是在List中定义了类似于查找的方法如get(int index)、indexOf(Object o),还包括一些重载add方法也是可以按照位置插入元素。这是由于List定义的集合类型决定的。其实对于子类LinkedList来说并不适合做查找,他内部是通过循环的方式从第一个来逐一往下查找直到循环index次数就找到了你给定序列的对象(源代码内部稍微做了一下优化就是如果给定的index序列大于size的一半,那么将从后往前开始循环找)

 

三、关于两个实现的子类。

    这里在啰嗦一遍它们的差异,ArrayList(数组,中间插入删除慢、按位置查找快)LinkedList(链表,中间插入删除快、按位置查找慢)。下面我们来分析一下产生这些差异的原因。

第一个:ArrayList

    源代码中它使用数组来存储的,由于数组是固定大小的,所必须先按照添加的扩容到相应的大小。由于数组长度是不变的所以得弄个新的。让后在插入添加的,尤其是往中间添加和删除是很繁琐的。下图我们很好的展示了它从中间插入的实现方式,同时数组是有下标的所以检索的时候速度就会较快。

java集合Collection的List ArrayList LinkedList 区别

第二个LinkedList:

    我们也结合图来看。从图中的变化可以看出它的每个元素都会自己保存上一个和下一个的位置。所以它的删除插入永远都不麻烦,改三个元素的令居就行。

但是由于它不像数组有下标记录,所单个查找就慢了。

    关于LinkedList内部如果实现元素保存自己令居的位置,它有一个自己的内部类Node,结构就和我们图中的节点完全一样保存上一个和下一个的对象引用。(注:这里顺带提一下LinkedList还实现了队列的接口,因为这种结构也可以完成队列的数据结构,所以LinkedList算是一个比较特别的实现类)

java集合Collection的List ArrayList LinkedList 区别

    最终它们的方法也不再单独介绍,以后发现比较特别的再补充。LinkedList由于还继承了队列的接口,所以它的有些方法是不能再List特性中使用的。