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

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

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

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

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

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

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

查询

public static void main(String[] args) {
        /*LinkedList*/
        List 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 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 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 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 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 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 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 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 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 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 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 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 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 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快,要看数据量,要根据具体插入、删除的位置而定。 

你可能感兴趣的:(Java基础,链表,数据结构,java,list)