ArrayList与LinkedList的区别

360 阅读3分钟

简介

ArrayList和LinkedList是Java中常用的两种集合类。它们都实现了List接口,但在内部实现和使用方式上有一些区别。

区别

数据存储方式

ArrayList是基于数组实现的动态数组,而LinkedList是基于链表实现的双向链表。这意味着ArrayList在内存中是连续存储的,而LinkedList的元素在内存中是分散存储的。

ArrayList是基于数组实现的,所以它的随机访问速度比较快。你可以通过索引直接访问和修改元素。而LinkedList的访问速度较慢,因为它需要从头或尾开始遍历链表,直到找到目标元素。

数据操作

在插入和删除操作上。ArrayList在末尾插入和删除元素的速度较快,因为它不需要移动其他元素。但在中间插入和删除元素时,需要移动后续元素,所以速度较慢。而LinkedList在任意位置插入和删除元素的速度都比较快,因为只需要修改前后节点的指针。

下图展示了ArrayList与LinkedList的数据结构图:

  • ArrayList:说明了ArrayList在数据操作过程,进行数据插入示意图,由此可以看出数组结构进行数据插入,需在指定索引位置进行插入,同时需要对数组进行扩容,而且插入位置后面的数组元素都需要往后移动,相对比较消耗性能。 image.png

  • LinkedList:说明了LinkedList在数据操作过程,进行元素删除示意图,由此可以看出LinkedList删除元素仅需要断开相应的链表节点即可快速完成。 image.png

下面是一些示例代码来说明它们的区别:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class ArrayListVsLinkedList {
    public static void main(String[] args) {
        List<Integer> arrayList = new ArrayList<>();
        List<Integer> linkedList = new LinkedList<>();

        // ArrayList添加元素
        long arrayListStartTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            arrayList.add(i);
        }
        long arrayListEndTime = System.nanoTime();
        long arrayListDuration = arrayListEndTime - arrayListStartTime;
        System.out.println("ArrayList添加元素所需时间:" + arrayListDuration + " 纳秒");

        // LinkedList添加元素
        long linkedListStartTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            linkedList.add(i);
        }
        long linkedListEndTime = System.nanoTime();
        long linkedListDuration = linkedListEndTime - linkedListStartTime;
        System.out.println("LinkedList添加元素所需时间:" + linkedListDuration + " 纳秒");

        // ArrayList随机访问元素
        long arrayListAccessStartTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            arrayList.get(i);
        }
        long arrayListAccessEndTime = System.nanoTime();
        long arrayListAccessDuration = arrayListAccessEndTime - arrayListAccessStartTime;
        System.out.println("ArrayList随机访问元素所需时间:" + arrayListAccessDuration + " 纳秒");

        // LinkedList随机访问元素
        long linkedListAccessStartTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            linkedList.get(i);
        }
        long linkedListAccessEndTime = System.nanoTime();
        long linkedListAccessDuration = linkedListAccessEndTime - linkedListAccessStartTime;
        System.out.println("LinkedList随机访问元素所需时间:" + linkedListAccessDuration + " 纳秒");

        // ArrayList在中间插入元素
        long arrayListInsertStartTime = System.nanoTime();
        for (int i = 0; i < 10000; i++) {
            arrayList.add(50000, i);
        }
        long arrayListInsertEndTime = System.nanoTime();
        long arrayListInsertDuration = arrayListInsertEndTime - arrayListInsertStartTime;
        System.out.println("ArrayList在中间插入元素所需时间:" + arrayListInsertDuration + " 纳秒");

        // LinkedList在中间插入元素
        long linkedListInsertStartTime = System.nanoTime();
        for (int i = 0; i < 10000; i++) {
            linkedList.add(50000, i);
        }
        long linkedListInsertEndTime = System.nanoTime();
        long linkedListInsertDuration = linkedListInsertEndTime - linkedListInsertStartTime;
        System.out.println("LinkedList在中间插入元素所需时间:" + linkedListInsertDuration + " 纳秒");
    }
}

这段代码演示了ArrayList和LinkedList在添加元素、随机访问元素和在中间插入元素时的性能差异。有兴趣的同学可以运行代码并观察输出结果,以更好地理解它们之间的区别。

总结

综合上面的说明解析来看,其实如果是日常开发进行少量的数据操作,无论使用ArrayList还是LinkedList都是体现不出差别的,只有的庞大的数据量下操作数据才能看到相对应的差距,不过具体适合多大数据量还是得根据实际场景进行压力测试验证进行数据分析再决定。