LinkedList与ArrayList二者性能简单PK

LinkedList与ArrayList二者性能简单PK

ArrayList与LinkedList

ArrayList底层是数组[],数字自带有索引下标,因此调用get()方法的时间复杂度为1;但是ArrayList在增删时除了定位到目标点以外,增加了元素或者删除了元素,都会对该目标节点后的元素产生影响,例如增加元素,那么长度变更,后续的所有元素都要向后挪一位,删除则是向前挪一位。
LinkedList底层是双向链表,链表嘛,查找时间复杂度近似O(n),毕竟要一个个查过去不是。但是增删只需要断开相邻的两个节点,然后插入或删去目标节点。
因此我们常常说,主查询使用ArrayList,频繁增删则使用LinkedList,但,为啥这个问题老是被问…为啥我工作里基本见不到LinkedList?最近准备面试看了下网上资料,部分博主贴出了代码演示,但是他们的删除操作,更多是删除固定位置,没有考虑到随机性。毕竟LinkedList增删元素时,如果都是很靠近首段和尾端,那么查找就不需要耗费那么多时间了,但恰恰查找元素才是LinkedList最耗费性能之处呀。

测试代码块

  @Test
    public void pkList() {
        ArrayList<Integer> arrayList = new ArrayList<>();
        LinkedList<Integer> linkedList = new LinkedList<>();
        // 分别插入10w条数据至list集合
        int length = 100000;
        long start = System.currentTimeMillis();
        for (int i = 0; i < length; i++) {
            arrayList.add(i);
        }
        long end = System.currentTimeMillis();
        System.out.println("arrayList插入10w条数据耗费时间为:" + (end - start) + "ms");
        long start1 = System.currentTimeMillis();
        for (int i = 0; i < length; i++) {
            linkedList.add(i);
        }
        long end1 = System.currentTimeMillis();
        System.out.println("linkedList插入10w条数据耗费时间为:" + (end1 - start1) + "ms");

        // 1.直接删除,测试remove时长

        int deleteLength = 1000;
        long deleteStart = System.currentTimeMillis();
        for (int i = 0; i < deleteLength; i++) {
            arrayList.remove(i);
        }
        long deleteEnd = System.currentTimeMillis();
        System.out.println("arrayList删除1000条数据耗费时间为:" + (deleteEnd - deleteStart) + "ms");

        long deleteStart1 = System.currentTimeMillis();
        for (int i = 0; i < deleteLength; i++) {
            linkedList.remove(i);
        }
        long deleteEnd1 = System.currentTimeMillis();
        System.out.println("linkedList删除1000条数据耗费时间为:" + (deleteEnd1 - deleteStart1) + "ms");

        // 2.随机元素删除,测试remove时长
        long deleteStart2 = System.currentTimeMillis();
        for (int i = 0; i < deleteLength; i++) {
            double random = Math.random();
            double random1 = Math.random();
            double index = (random * 1000 * random1 * 500) + 100;
            arrayList.remove(index);
        }
        long deleteEnd2 = System.currentTimeMillis();
        System.out.println("arrayList随机删除1000条数据耗费时间为:" + (deleteEnd2 - deleteStart2) + "ms");

        long deleteStart3 = System.currentTimeMillis();
        for (int i = 0; i < deleteLength; i++) {
            double random = Math.random();
            double random1 = Math.random();
            double index = (random * 1000 * random1 * 500) + 100;
            linkedList.remove(index);
        }
        long deleteEnd3 = System.currentTimeMillis();
        System.out.println("linkedList随机删除1000条数据耗费时间为:" + (deleteEnd3 - deleteStart3) + "ms");
    }

输出结果

arrayList插入10w条数据耗费时间为:11ms
linkedList插入10w条数据耗费时间为:7ms
arrayList删除1000条数据耗费时间为:33ms
linkedList删除1000条数据耗费时间为:2ms
arrayList随机删除1000条数据耗费时间为:121ms
linkedList随机删除1000条数据耗费时间为:235ms

总结

主查找ArrayList,增删频繁分情况:①如果List长度很短,小于1000,那么二者性能接近,图方便可以直接无脑ArrayList;②List长度很长,1w到100w条,增删都靠近首尾端,那么考虑性能采用LinkedList,如果位置非常随机,那么还是ArrayList好一些(我试了100w,随机删除范围扩大了一倍,ArrayList差不多是1.3s,LinkedList差不多4.9s,但是固定删除时,靠近首尾端,LinkedList耗时0-2ms,ArrayList耗时200-223ms);

一般情况下用ArrayList即可,除非考虑到接近首尾两端这个情况,不然几乎都是ArrayList;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值