全网最详细的--ArrayList与LinkedList的区别与耗时对比

1、ArrayList通过数组实现,是一片连续的内存区域,可以用下标直接定位到内存地址,查询效率高;因为插入和删除需要移动内存块,插入和删除元素效率低。

2、LinkedList通过链表实现,元素之间直接通过指针相互关联,查询需要遍历链表,效率较低;插入和删除只需要改变指针指向,插入和删除效率高。

下面来验证一下上述内容,先说一下结论:

并不是所有的删除和插入操作LinkedList都比ArrayList快!

我们将删除和插入分为几种情况来验证

头部插入(删除)、中部插入(删除)、尾部插入(删除)

查询

public static void main(String[] args) {
        /*LinkedList*/
        List<String> linkedList = new LinkedList<>();
        for (int i=0;i<=10000000;i++){
            linkedList.add("linked");
        }
        Long startTime = System.currentTimeMillis();
        linkedList.get(4678645);
        System.out.println("LinkedList耗时:" + (System.currentTimeMillis()-startTime) + "ms");
        
        /*ArrayList*/
        List<String> arrayList = new ArrayList<>();
        for (int i=0;i<=10000000;i++){
            arrayList.add("array");
        }
        Long startTime1 = System.currentTimeMillis();
        arrayList.get(4678645);
        System.out.println("ArrayList耗时:" + (System.currentTimeMillis()-startTime1) + "ms");

    }


LinkedList耗时:27ms
ArrayList耗时:0ms

LinkedList和ArrayList在一千万个元素中随机查询,可以看到ArrayList相对LinkedList快很多。

 头部删除

public static void main(String[] args) {
        /*LinkedList*/
        List<String> linkedList = new LinkedList<>();
        for (int i=0;i<=10000000;i++){
            linkedList.add("linked");
        }
        Long startTime = System.currentTimeMillis();
        linkedList.remove(0);
        System.out.println("LinkedList耗时:" + (System.currentTimeMillis()-startTime) + "ms");

        /*ArrayList*/
        List<String> arrayList = new ArrayList<>();
        for (int i=0;i<=10000000;i++){
            arrayList.add("array");
        }
        Long startTime1 = System.currentTimeMillis();
        arrayList.remove(0);
        System.out.println("ArrayList耗时:" + (System.currentTimeMillis()-startTime1) + "ms");

    }


LinkedList耗时:0ms
ArrayList耗时:4ms

在头部删除,LinkedList要比ArrayList快。因为ArrayList在删除后有近一千万个元素要移动;而LinkedList只需要将头部的指针删除即可。

中部删除

public static void main(String[] args) {
    /*LinkedList*/
    List<String> linkedList = new LinkedList<>();
    for (int i=0;i<=10000000;i++){
        linkedList.add("linked");
    }
    Long startTime = System.currentTimeMillis();
    linkedList.remove(5000000);
    System.out.println("LinkedList耗时:" + (System.currentTimeMillis()-startTime) + "ms");

    /*ArrayList*/
    List<String> arrayList = new ArrayList<>();
    for (int i=0;i<=10000000;i++){
        arrayList.add("array");
    }
    Long startTime1 = System.currentTimeMillis();
    arrayList.remove(5000000);
    System.out.println("ArrayList耗时:" + (System.currentTimeMillis()-startTime1) + "ms");

}

LinkedList耗时:14ms
ArrayList耗时:1ms

在中部删除, LinkedList反而要比ArrayList要慢,是因为LinkedList遍历五百万的元素比ArrayList移动五百万的元素还要慢。

尾部删除

public static void main(String[] args) {
    /*LinkedList*/
    List<String> linkedList = new LinkedList<>();
    for (int i=0;i<=10000000;i++){
        linkedList.add("linked");
    }
    Long startTime = System.currentTimeMillis();
    linkedList.remove(9999999);
    System.out.println("LinkedList耗时:" + (System.currentTimeMillis()-startTime) + "ms");

    /*ArrayList*/
    List<String> arrayList = new ArrayList<>();
    for (int i=0;i<=10000000;i++){
        arrayList.add("array");
    }
    Long startTime1 = System.currentTimeMillis();
    arrayList.remove(9999999);
    System.out.println("ArrayList耗时:" + (System.currentTimeMillis()-startTime1) + "ms");

}

LinkedList耗时:0ms
ArrayList耗时:0ms

 在尾部删除,ArrayList不需要移动元素,LinkedList只需要删除尾部指针,因此两者耗时相近。

头部插入

public static void main(String[] args) {
    /*LinkedList*/
    List<String> linkedList = new LinkedList<>();
    for (int i=0;i<=10000000;i++){
        linkedList.add("linked");
    }
    Long startTime = System.currentTimeMillis();
    linkedList.add(0,"123");
    System.out.println("LinkedList耗时:" + (System.currentTimeMillis()-startTime) + "ms");

    /*ArrayList*/
    List<String> arrayList = new ArrayList<>();
    for (int i=0;i<=10000000;i++){
        arrayList.add("array");
    }
    Long startTime1 = System.currentTimeMillis();
    arrayList.add(0,"123");
    System.out.println("ArrayList耗时:" + (System.currentTimeMillis()-startTime1) + "ms");

}

LinkedList耗时:0ms
ArrayList耗时:7ms

头部插入与头部删除一样,ArrayList同样需要移动近一千万的元素,而LinkedList只需要删除头部的指针即可。LinkedList比ArrayList快。

中部插入

public static void main(String[] args) {
    /*LinkedList*/
    List<String> linkedList = new LinkedList<>();
    for (int i=0;i<=10000000;i++){
        linkedList.add("linked");
    }
    Long startTime = System.currentTimeMillis();
    linkedList.add(5000000,"123");
    System.out.println("LinkedList耗时:" + (System.currentTimeMillis()-startTime) + "ms");

    /*ArrayList*/
    List<String> arrayList = new ArrayList<>();
    for (int i=0;i<=10000000;i++){
        arrayList.add("array");
    }
    Long startTime1 = System.currentTimeMillis();
    arrayList.add(5000000,"123");
    System.out.println("ArrayList耗时:" + (System.currentTimeMillis()-startTime1) + "ms");

}

LinkedList耗时:14ms
ArrayList耗时:3ms

在中部插入与删除类似,LinkedList的遍历速度没有ArrayList移动元素的速度快。ArrayList比LinkedList快。 

尾部插入

public static void main(String[] args) {
    /*LinkedList*/
    List<String> linkedList = new LinkedList<>();
    for (int i=0;i<=10000000;i++){
        linkedList.add("linked");
    }
    Long startTime = System.currentTimeMillis();
    linkedList.add("123");
    System.out.println("LinkedList耗时:" + (System.currentTimeMillis()-startTime) + "ms");

    /*ArrayList*/
    List<String> arrayList = new ArrayList<>();
    for (int i=0;i<=10000000;i++){
        arrayList.add("array");
    }
    Long startTime1 = System.currentTimeMillis();
    arrayList.add("123");
    System.out.println("ArrayList耗时:" + (System.currentTimeMillis()-startTime1) + "ms");

}

LinkedList耗时:0ms
ArrayList耗时:0ms

尾部插入与尾部删除类似,LinkedList不需要遍历,ArrayList不需要移动元素,因此两者效率相近。


通过以上验证可知:

并不是所有的插入、删除,LinkedList都要比ArrayList快,要看数据量,要根据具体插入、删除的位置而定。 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值