1.Deque和Stack的区别以及ArrayDeque、LinkedList这两个类的不同

DequeStack 在 Java 里经常会拿来比较,因为它们都能做"栈"的工作,但实际上它们的设计理念和应用范围有很大区别。


📌 1. Stack

arduino 复制代码
Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
stack.pop();  // 出栈 -> 2
  • 继承关系Stack 继承自 Vector(线程安全的动态数组)。

  • 特点

    • 早期的栈实现(比较古老)。
    • 方法都是同步的(synchronized),在多线程下保证安全。
    • 但是因为同步的原因,单线程环境下效率会偏低。
    • 只能作为 栈(LIFO) 使用。

📌 2. Deque

arduino 复制代码
Deque<Integer> deque = new ArrayDeque<>();
deque.push(1);   // 等价于 addFirst(1)
deque.push(2);
deque.pop();     // 出栈 -> 2
  • 继承关系Deque 是一个接口,代表 双端队列

  • 常见实现类ArrayDequeLinkedList

  • 特点

    • Stack 新,推荐在栈场景中用 Deque 代替 Stack

    • 方法没有同步锁,单线程环境下效率更高。

    • 灵活:既能作为 栈(LIFO) 使用,也能作为 队列(FIFO) 使用。

      • addFirst() / removeFirst() → 栈操作。
      • addLast() / removeFirst() → 队列操作。

📌 3. 主要区别总结

特性 Stack Deque (ArrayDeque/LinkedList)
数据结构 基于 Vector(数组 + 同步) 双端队列(数组/链表实现)
线程安全 线程安全(有同步锁) 非线程安全(更快)
使用场景 只能作为栈使用 既可栈,也可队列
推荐程度 过时,不推荐 官方推荐用它代替 Stack

📌 4. 官方推荐

Java 官方文档明确说明:

For stack operations, use Deque instead of Stack.

所以,在写 LeetCode 或一般算法题时:

ini 复制代码
Deque<Integer> stack = new ArrayDeque<>();

是最佳选择。


好问题 👍,我们继续深入。

在 Java 里,Deque 是一个接口,而 ArrayDequeLinkedList 是它的两个常用实现类。虽然都能实现 双端队列/栈,但它们的底层机制和性能差异很大。


📌 ArrayDeque vs LinkedList 对比

特性 ArrayDeque LinkedList
底层结构 动态数组(循环数组实现) 双向链表
内存占用 连续内存,节省空间 每个节点额外存储 prevnext 指针,内存占用更大
随机访问 (直接按索引访问 O(1)) (必须遍历链表 O(n))
插入/删除 在队列头尾 (O(1),但数组可能扩容) 在队列头尾 (O(1),不需扩容)
中间插入/删除 (需要移动元素 O(n)) (只需改指针 O(1),但要先遍历找到位置 O(n))
缓存命中 高(数组连续存储,CPU 缓存友好) 低(链表节点分散,可能导致 cache miss)
扩容问题 容量不够时,会 自动扩容 2 倍 不需要扩容
线程安全 非线程安全 非线程安全
常见应用 栈/队列/单调栈(算法题推荐) 需要频繁 在中间插入/删除 时使用

📌 代码示例

1. ArrayDeque

arduino 复制代码
Deque<Integer> deque = new ArrayDeque<>();
deque.addFirst(1);  // 插入到队首
deque.addLast(2);   // 插入到队尾
System.out.println(deque.removeFirst()); // 1
System.out.println(deque.removeLast());  // 2

2. LinkedList

arduino 复制代码
Deque<Integer> deque = new LinkedList<>();
deque.addFirst(1);
deque.addLast(2);
System.out.println(deque.removeFirst()); // 1
System.out.println(deque.removeLast());  // 2

两者用法几乎完全一致,因为都实现了 Deque 接口。


📌 选择建议

  • 算法题 / LeetCode / 栈 / 队列 → ✅ ArrayDeque(更快,更省内存)
  • 需要频繁在中间插入/删除 → ✅ LinkedList(不用移动数组元素)
  • 几乎不用随机访问 ,只是做链表操作 → LinkedList 也 OK,但一般性能不如 ArrayDeque

💡 总结一句话:

👉 ArrayDeque 是通用高效的栈/队列实现,推荐首选。LinkedList 适合需要大量链表特性的场景。


相关推荐
许彰午7 小时前
我手写了一个 Java 内存数据库(二):B+ 树的插入与分裂
java·开发语言·面试
weisian15112 小时前
基础篇--概念原理-2-参数是什么?——从原理到实战,一篇讲透
面试·职场和发展·模型参数·7b和70b·参数=规则,不是原始数据
AI人工智能+电脑小能手13 小时前
【大白话说Java面试题】【Java基础篇】第26题:Java的抽象类和接口有哪些区别
java·开发语言·面试
逻辑驱动的ken15 小时前
Java高频面试考点场景题20
java·开发语言·深度学习·面试·职场和发展
Wect15 小时前
深度剖析浏览器跨域问题
前端·面试·浏览器
刀法如飞17 小时前
Java数组去重的20种实现方式——指导AI解决不同问题的思路
java·算法·面试
ayqy贾杰17 小时前
Cursor SDK发布!开发者可直接搬走其内核
前端·vue.js·面试
JAVA面经实录9171 天前
Java企业级工程化·终极完整版背诵手册(无遗漏、全覆盖、面试+落地通用)
java·开发语言·面试
小程故事多_801 天前
[大模型面试系列] 多轮对话 Agent 设计实战(含窗口优化 + 工具调用精髓)
人工智能·面试·职场和发展
AI人工智能+电脑小能手1 天前
【大白话说Java面试题】【Java基础篇】第24题:Java面向对象有哪些特征
java·开发语言·后端·面试