面试官又双叒问这个问题了?ArrayList 和 LinkedList的区别是什么?经常再用但是有时候就是答不上来。 这个时候回答的时候肯定回答的不全面,随便糊弄一下。 那么到底有啥区别,我们今天好好分析一下
一、 底层结构:
怎么看他们的底层结构呢,你随便创建一个java文件,然后在里面创建一个ArrayList 和LinkedList然后点击就可以看到底层了,就像这样:
ArrayList: 上面这串英文翻译出来大概就是告诉我们它的底层是一个数组
LinkedList:
前一个节点,下一个节点,这就是一个链表结构的
二、 性能方面,我们测试那种极限的情况
场景1:随机访问
java
// 初始化10万数据
List<Integer> arrayList = new ArrayList<>(1000000);
List<Integer> linkedList = new LinkedList<>();
for (int i = 0; i < 1000000; i++) {
arrayList.add(i);
linkedList.add(i);
}
// 测试:访问第500000个元素
long start = System.nanoTime();
arrayList.get(500000);
long arrayTime = System.nanoTime() - start;
start = System.nanoTime();
linkedList.get(500000);
long linkedTime = System.nanoTime() - start;
System.out.println("ArrayList 耗时:" + arrayTime + " 纳秒");
System.out.println("LinkedList 耗时:" + linkedTime + " 纳秒");
实测结果 :ArrayList 比 LinkedList 的查询速度快很多

场景2:头部疯狂插入数据
java
// 测试:在头部插入10000次
// 初始化10万数据
List<Integer> arrayList = new ArrayList<>(1000000);
List<Integer> linkedList = new LinkedList<>();
for (int i = 0; i < 1000000; i++) {
arrayList.add(i);
linkedList.add(i);
}
long start =0 ;
start = System.nanoTime();
for (int i = 0; i < 10000; i++) {
arrayList.add(0, i);
}
System.out.println("ArrayList 头部插入耗时:" + (System.nanoTime() - start));
start = System.nanoTime();
for (int i = 0; i < 10000; i++) {
((LinkedList<Integer>) linkedList).addFirst(i);
}
System.out.println("LinkedList 头部插入耗时:" + (System.nanoTime() - start));
实测结果 :LinkedList速度快很多,ArrayList 的数组迁移代价太高。

场景3:中部删除
java
// 初始化10万数据
List<Integer> arrayList = new ArrayList<>(1000000);
List<Integer> linkedList = new LinkedList<>();
for (int i = 0; i < 1000000; i++) {
arrayList.add(i);
linkedList.add(i);
}
// 测试:删除中间1000个元素 (从索引50000开始)
long start = System.nanoTime();
start = System.nanoTime();
for (int i = 0; i < 1000; i++) {
arrayList.remove(50000);
}
System.out.println("ArrayList 中部删除耗时:" + (System.nanoTime() - start));
start = System.nanoTime();
ListIterator<Integer> it = linkedList.listIterator(50000);
for (int i = 0; i < 1000; i++) {
it.next();
it.remove();
}
System.out.println("LinkedList 中部删除耗时:" + (System.nanoTime() - start));
关键发现:
- LinkedList 删除并不总是快! 找到删除位置 (O(n)) + 删除 (O(1)) = 整体仍是 O(n)
- Iterator 是救星! 用
ListIterator
定位后批量删除,避免重复遍历,效率反超 ArrayList
三、 内存情况
-
ArrayList:
-
基础消耗小 :数组本身很轻量 优化TIP :
new ArrayList<>(10000)
预分配大小,避免反复扩容 -
LinkedList : 每个元素都是节点 :除了数据,还要存前后指针 内存碎片警告! 节点分散在内存各处,对CPU缓存不友好
四、 LinkedList的使用场景
-
需要快速合并集合 :
linkedList.addAll(anotherList)
直接拼接链表,无需复制元素! -
中间位置极高频插入/删除 :
前提:已通过Iterator定位好位置! 后续操作才是O(1)