面试官经常问的ArrayList 和 LinkedList的区别

面试官又双叒问这个问题了?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));

关键发现

  1. LinkedList 删除并不总是快! 找到删除位置 (O(n)) + 删除 (O(1)) = 整体仍是 O(n)
  2. Iterator 是救星!ListIterator 定位后批量删除,避免重复遍历,效率反超 ArrayList

三、 内存情况

  • ArrayList

  • 基础消耗小 :数组本身很轻量 优化TIPnew ArrayList<>(10000) 预分配大小,避免反复扩容

  • LinkedList每个元素都是节点 :除了数据,还要存前后指针 内存碎片警告! 节点分散在内存各处,对CPU缓存不友好


四、 LinkedList的使用场景

  1. 需要快速合并集合
    linkedList.addAll(anotherList) 直接拼接链表,无需复制元素

  2. 中间位置极高频插入/删除
    前提:已通过Iterator定位好位置! 后续操作才是O(1)


相关推荐
柠檬味拥抱1 小时前
Java 实现可靠的 WAV 音频拼接:从结构解析到完整可播放的高质量合并方案
后端
DyLatte1 小时前
AI时代的工作和成长
java·后端·程序员
Java水解1 小时前
初识MYSQL —— 基本查询
后端·mysql
用户497357337981 小时前
夏曹俊:C++零基础到工程实战,视频+课件完结
后端
databook2 小时前
manim边做边学--文字创建销毁的打字机效果
后端·python·动效
林太白2 小时前
八大数据结构
前端·后端·算法
林太白2 小时前
Rust14-字典数据
后端·rust
国思RDIF框架2 小时前
国思RDIF低代码快速开发框架 v6.2.2版本发布
前端·vue.js·后端
Java水解2 小时前
Java基础------真实大厂面试题汇总(含答案)
java·后端·面试
L.EscaRC2 小时前
面向 Spring Boot 的 JVM 深度解析
jvm·spring boot·后端