栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JAVA源码学习之集合-List总结

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JAVA源码学习之集合-List总结

目录

前言

正文

ArrayList和linkList的区别

添加

查询

 ArrayList和Vector区别


前言

前面几章我们研究了,ArrayList、linkList、Vector和Stack的源码,下面我们对相关的几个List进行对比和总结

正文

ArrayList和linkList的区别

平常总能听到同学们说,ArrayList与linkList相比查询快,插入慢,我们下面就用代码验证下

添加
  • 尾部添加
//1000
ArrayList arrayList1 = new ArrayList<>(0);
		linkedList linkedList1 = new linkedList<>();
		long arrayStartTime = System.currentTimeMillis();
		for(int i = 0;  i < 1000; i++) {
			arrayList1.add(i);
		}
		System.out.println("ArrayList add Time difference: " + (System.currentTimeMillis() - arrayStartTime));

		long linkStartTime1 = System.currentTimeMillis();
		for(int i = 0;  i < 1000; i++) {
			arrayList1.add(i);
		}

		System.out.println("ArrayList add Time difference: " + (System.currentTimeMillis() - linkStartTime1));

//输出
 

/ArrayList last add Time difference: 0
//linkedList last add Time difference: 0】

//没有区别, 把循环值增大10倍

//10000

ArrayList last add Time difference: 2
linkedList last add Time difference: 1

//差了1, 又运行了几次,出现相同的次数机率也很大, 和系统运行有关系,继续把循环值增大10倍

//100000

ArrayList last add Time difference: 8
linkedList last add Time difference: 4

//差了4,多运行了几次,得到的结果都是 ArrayList的时间大于linkList

结论: 尾部添加的时候,ArrayList的速度慢于linkList (是在一定量的基础上),这是因为ArrList尾部插入时候需要扩容,而,linkList只需要在last节点后添加一个新节点就可以了

  • 中间插入
for(int i = 0;  i < 1000; i++) {
			long arrayListMidAddStartTime = System.currentTimeMillis();
			arrayList1.add(i, i);
			System.out.println("ArrayList Mid add " + i + " Time difference: " + (System.currentTimeMillis() - arrayListMidAddStartTime));


			long linkListMidAddStartTime = System.currentTimeMillis();
			linkedList1.add(i, i);
			System.out.println("linkedList Mid add " + i + " Time difference: " + (System.currentTimeMillis() - linkListMidAddStartTime));
		}

//输出

ArrayList Mid add 0 Time difference: 0
linkedList Mid add 0 Time difference: 0
ArrayList Mid add 1 Time difference: 0
linkedList Mid add 1 Time difference: 0
ArrayList Mid add 2 Time difference: 0
linkedList Mid add 2 Time difference: 0

。。。。

linkedList Mid add 997 Time difference: 0
ArrayList Mid add 998 Time difference: 1
linkedList Mid add 998 Time difference: 0
ArrayList Mid add 999 Time difference: 0
linkedList Mid add 999 Time difference: 0

//基本没有区别, 把循环值增大10

//10000

ArrayList Mid add 0 Time difference: 1
linkedList Mid add 0 Time difference: 0
ArrayList Mid add 1 Time difference: 1
linkedList Mid add 1 Time difference: 0
ArrayList Mid add 2 Time difference: 0
linkedList Mid add 2 Time difference: 0

。。。。

linkedList Mid add 9997 Time difference: 0
ArrayList Mid add 9998 Time difference: 0
linkedList Mid add 9998 Time difference: 1
ArrayList Mid add 9999 Time difference: 0
linkedList Mid add 9999 Time difference: 0

//基本没有区别, 把循环值增大10
....
ArrayList Mid add 87948 Time difference: 0
linkedList Mid add 87948 Time difference: 2
ArrayList Mid add 87949 Time difference: 0
linkedList Mid add 87949 Time difference: 3
ArrayList Mid add 87950 Time difference: 0
linkedList Mid add 87950 Time difference: 3
ArrayList Mid add 87951 Time difference: 0
linkedList Mid add 87951 Time difference: 5
ArrayList Mid add 87952 Time difference: 0
linkedList Mid add 87952 Time difference: 4
ArrayList Mid add 87953 Time difference: 0
linkedList Mid add 87953 Time difference: 4
....
ArrayList Mid add 99991 Time difference: 0
linkedList Mid add 99991 Time difference: 5
ArrayList Mid add 99992 Time difference: 0
linkedList Mid add 99992 Time difference: 6
ArrayList Mid add 99993 Time difference: 0
linkedList Mid add 99993 Time difference: 8
ArrayList Mid add 99994 Time difference: 0
linkedList Mid add 99994 Time difference: 5
ArrayList Mid add 99995 Time difference: 0
linkedList Mid add 99995 Time difference: 6
ArrayList Mid add 99996 Time difference: 0
linkedList Mid add 99996 Time difference: 5
ArrayList Mid add 99997 Time difference: 0
linkedList Mid add 99997 Time difference: 6
ArrayList Mid add 99998 Time difference: 0
linkedList Mid add 99998 Time difference: 6
ArrayList Mid add 99999 Time difference: 0
linkedList Mid add 99999 Time difference: 1

//开始有明显的差别了

80000时候 ArrayList的时间明显小于linkList

这个是因为,ArrayList插入的时候可以直接找到下标进行插入, 而linkList需要从头遍历,然后找到对应值,

 public void add(int index, E element) {
        checkPositionIndex(index);

        if (index == size) //这是为啥当是99999的时候和ArrayList时间几乎没区别了
            linkLast(element);
        else
            linkBefore(element, node(index));
    }

     void linkBefore(E e, Node succ) {
        // assert succ != null;
        final Node pred = succ.prev;
        final Node newNode = new Node<>(pred, e, succ);
        succ.prev = newNode;
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        size++;
        modCount++;
    }

有人可能问,ArrayList需要扩容呢,为什么linkList的时间会更大呢。

所以猜测,应该是有一个界限,因为ArrayList 只有等size大于length的时候才需要扩容,所以”index“大于一定的数量后,向较于linkList的遍历,ArrayList的扩容所需要的时间可以是忽略不计的。

所以中间插入所需要的时间应该是这样的

 这个界限值应该根据不同的硬件性能应该是不同的,

linkedList Mid add 24993 Time difference: 1
ArrayList Mid add 24994 Time difference: 0
linkedList Mid add 24994 Time difference: 0
ArrayList Mid add 24995 Time difference: 0
linkedList Mid add 24995 Time difference: 0
ArrayList Mid add 24996 Time difference: 0
linkedList Mid add 24996 Time difference: 0
ArrayList Mid add 24997 Time difference: 0
linkedList Mid add 24997 Time difference: 1
ArrayList Mid add 24998 Time difference: 0
linkedList Mid add 24998 Time difference: 0
ArrayList Mid add 24999 Time difference: 0
linkedList Mid add 24999 Time difference: 0
...
linkedList Mid add 39991 Time difference: 1
ArrayList Mid add 39992 Time difference: 0
linkedList Mid add 39992 Time difference: 0
ArrayList Mid add 39993 Time difference: 0
linkedList Mid add 39993 Time difference: 1
ArrayList Mid add 39994 Time difference: 0
linkedList Mid add 39994 Time difference: 1
ArrayList Mid add 39995 Time difference: 0
linkedList Mid add 39995 Time difference: 1
ArrayList Mid add 39996 Time difference: 0
linkedList Mid add 39996 Time difference: 2
ArrayList Mid add 39997 Time difference: 0
linkedList Mid add 39997 Time difference: 0
ArrayList Mid add 39998 Time difference: 0
linkedList Mid add 39998 Time difference: 1
ArrayList Mid add 39999 Time difference: 0
linkedList Mid add 39999 Time difference: 1

我的电脑上在25000到40000的时候出现了具体的差别

查询
for(int i = 0;  i < 1000; i++) {
			long arrayListGetStartTime = System.currentTimeMillis();
			arrayList1.get(i);
			System.out.println("ArrayList get " + i + " Time difference: " + (System.currentTimeMillis() - arrayListGetStartTime));


			long linkListGetStartTime = System.currentTimeMillis();
			linkedList1.get(i);
			System.out.println("linkedList get " + i + " Time difference: " + (System.currentTimeMillis() - linkListGetStartTime));
		}

输出

//1000
ArrayList get 992 Time difference: 0
linkedList get 992 Time difference: 0
ArrayList get 993 Time difference: 0
linkedList get 993 Time difference: 0
ArrayList get 994 Time difference: 0
linkedList get 994 Time difference: 0
ArrayList get 995 Time difference: 0
linkedList get 995 Time difference: 0
ArrayList get 996 Time difference: 0
linkedList get 996 Time difference: 0
ArrayList get 997 Time difference: 0
linkedList get 997 Time difference: 0
ArrayList get 998 Time difference: 0
linkedList get 998 Time difference: 0
ArrayList get 999 Time difference: 0
linkedList get 999 Time difference: 0

//没有区别,将循环值增大10倍

ArrayList get 9992 Time difference: 0
linkedList get 9992 Time difference: 0
ArrayList get 9993 Time difference: 0
linkedList get 9993 Time difference: 0
ArrayList get 9994 Time difference: 0
linkedList get 9994 Time difference: 0
ArrayList get 9995 Time difference: 0
linkedList get 9995 Time difference: 0
ArrayList get 9996 Time difference: 0
linkedList get 9996 Time difference: 0
ArrayList get 9997 Time difference: 0
linkedList get 9997 Time difference: 0
ArrayList get 9998 Time difference: 0
linkedList get 9998 Time difference: 0
ArrayList get 9999 Time difference: 0
linkedList get 9999 Time difference: 0

//任然没有区别, 增大到50000,因为linkListget的时候是先用中间值比较,然后选择从头遍历,还是
//从尾遍历, 具体代码请看linkList那章或则看下源码
ArrayList get 49993 Time difference: 0
linkedList get 49993 Time difference: 0
ArrayList get 49994 Time difference: 0
linkedList get 49994 Time difference: 0
ArrayList get 49995 Time difference: 0
linkedList get 49995 Time difference: 0
ArrayList get 49996 Time difference: 0
linkedList get 49996 Time difference: 0
ArrayList get 49997 Time difference: 0
linkedList get 49997 Time difference: 0
ArrayList get 49998 Time difference: 0
linkedList get 49998 Time difference: 0
ArrayList get 49999 Time difference: 0
linkedList get 49999 Time difference: 1

//区别仍然不大, 把上面的添加元素增大10倍,然后查找的循环在增大10倍
linkedList get 499990 Time difference: 4
ArrayList get 499991 Time difference: 0
linkedList get 499991 Time difference: 4
ArrayList get 499992 Time difference: 0
linkedList get 499992 Time difference: 5
ArrayList get 499993 Time difference: 0
linkedList get 499993 Time difference: 5
ArrayList get 499994 Time difference: 0
linkedList get 499994 Time difference: 5
ArrayList get 499995 Time difference: 0
linkedList get 499995 Time difference: 4
ArrayList get 499996 Time difference: 0
linkedList get 499996 Time difference: 4
ArrayList get 499997 Time difference: 0
linkedList get 499997 Time difference: 5
ArrayList get 499998 Time difference: 0
linkedList get 499998 Time difference: 4
ArrayList get 499999 Time difference: 0
linkedList get 499999 Time difference: 4
//有明显的区别了

有差别的原因是因为ArrayList数据结构是数组,可以通过下标直接找打,而linkList是链表是需要遍历链表找到位置,所需时间请看下图

有兴趣的小伙伴可以,自己用代码运行下

 ArrayList和Vector区别

相同处: 数据结构上都是使用了数组,所以相关操作原理是一样的, 扩容操作都是使用的,新定义一个数组,然后通过System.copyOf进行复制

不同点:

Vector相关的方法上都使用的了 synchronized 关键字做了修饰,所以他是线程安全的,相对的性能就不如ArrayList

然后还有一些小细节区别,比如ArrayList的DEFAULTCAPACITY_EMPTY_ELEMENTDATA和

EMPTY_ELEMENTDATA

Vector的扩容向量和扩容向量为0时,是扩容一倍,而ArrayList是1.5等等,这些在前面两章研究过了,就不做过多的叙述了

下一章开始研究另一个集合Set

上一章                                                                                                                                    下一章                                                                                                                 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/459692.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号