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

ArrayList与LinkedList区别

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

ArrayList与LinkedList区别

ArraysList和LinkedList都是java中存放数据的集合。那么这两者都在什么场景下使用呢?

ArraysList

ArraysList底层实现是数组,数组结构的特点是增删慢、查询快。这里的增删慢指不是在尾部增删数据慢,而是在非尾部增删数据慢。因为ArrayList的底层实现是新建立一个数组,然后通过copy操作来复制数据,从而达到增删数据的效果。这个copy操作,就浪费了性能。

ArrayList可以指定容量。如果不指定容量,那么初始容量为0。当第一次调用add方法添加元素的时候,扩容到10。此后再需要扩容的时候,按照原来1.5倍空间进行扩容。扩容的本质也是新建一个数组,然后copy数据进行扩容。也很浪费性能。因此可以规定初始容量,减少ArrayList的扩容触发。

参考文章:浅谈ArrayList及其扩容机制

LinkedList


由源码可以看到,LinkedList内部维护了first和last头部和尾部节点。每个节点Node还维护了next和prev上一个和下一个节点。其是一个双向链表。链表的特点是查询慢,增删快。因为维护了上一个Node和下一个Node,所以增删就是对Node指针的改变,不需要进行数据的copy等操作,所以增删快。因为链表中没有角标索引,所以查询起来速度慢。

LinkedList没有最大容量个初始容量,也不需要扩容,理论只要内存够大,可以存无限的值。所以扩容带来的性能损耗都没有。

参考文章:linkedList详解

实际应用

在一个数据量大,数据传输频繁的场景中,需要用一个集合接收传输的数据,然后再用另外一个线程去消费集合中接收到的数据。要求先进先出,先消费集合前面的数据,再消费集合后面的元素。

上述场景中应该选择哪个集合呢?通过分析可以发现,添加元素都是往集合的尾部添加,所以ArrayList和LinkedList都可以,性能都不受影响。而消费数据是从集合头部开始消费的,因为数据量大,传输频繁,所以这里需要消费完一个数据,就删除一个数据,避免造成内存空间的浪费。那么删除数据,用哪个快呢?肯定是用LinkedList更快。因为这里不涉及到数据的查询,就是消费集合中的第一个元素,所以LinkedList查询慢的弊端在这里显现不出来。
此外,数量大,数据传输频繁,那么ArrayList很可能会触发扩容机制而影响性能,所以这里使用LinkedList更合适。

下面通过实验证明:

public static void main(String[] args) {
        //使用ArrayList
        ArrayList list=new ArrayList();
        //启动线程添加数据,添加一百万条数据
        new Thread(){
            @Override
            public void run() {
                for (int i=0;i<1000000;i++){
                    list.add(i);
                    logger.error("add:"+i);
                }
            }
        }.start();
        //另一个线程消费数据,当消费完成后退出循环,并打印消费的数据
        new Thread(){
            @Override
            public void run() {
                while (true){

                try {
                    Object remove = list.remove(0);
                    logger.error("data:" + remove);
                }catch (Exception e){
                   break;
                }

                }
            }
        }.start();

    }

通过日志可以看到开始消费的时间为13:19:41.928,结束消费的时间为13:21:39.505,将近两分钟。

改成用LinkedList:

public static void main(String[] args) {
        //使用ArrayList
        LinkedList list=new LinkedList();
        //启动线程添加数据,添加一百万条数据
        new Thread(){
            @Override
            public void run() {
                for (int i=0;i<1000000;i++){
                    list.add(i);
                    logger.error("add:"+i);
                }
            }
        }.start();
        //另一个线程消费数据,当消费完成后退出循环,并打印消费的数据
        new Thread(){
            @Override
            public void run() {
                while (true){

                try {
                    Object remove = list.remove(0);
                    logger.error("data:" + remove);
                }catch (Exception e){
                   break;
                }

                }
            }
        }.start();

    }

通过日志发现开始消费和结束消费的时间为22秒左右。可见LinkedList更适合该场景。

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

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

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