Java Queue
Java Queue
25. Queue 与 Deque 的区别?
回答:
Queue 是先进先出(FIFO)结构,而 Deque 是双端队列,既支持 FIFO,也支持栈(LIFO)操作,功能更灵活。
分析:
Queue 接口定义了一个单向的队列结构,强调的是按添加顺序依次处理元素,典型操作包括 offer() 添加、poll() 移除头元素、peek() 查看头部元素。Queue 的实现类如 PriorityQueue 和 LinkedList 等,分别用于优先级调度或通用队列功能。而 Deque(Double-Ended Queue)接口则是 Queue 的增强版,支持从队列两端进行插入和删除。它既可以作为队列使用(如 addLast() / pollFirst()),也可以模拟栈结构(如 push() / pop())。常用实现包括 ArrayDeque 和 LinkedList,其中 ArrayDeque 更适合作为栈或队列,性能优于 Stack 和 LinkedList。Deque 的灵活性使其在数据结构转换、滑动窗口、缓存实现中更为高效。
26. 在 Queue 中 poll() 和 remove() 有什么区别?
回答:
poll() 和 remove() 都用于删除并返回队首元素,但在队列为空时的行为不同:poll() 返回 null,而 remove() 抛出 NoSuchElementException。
分析:
Queue 接口提供了两种类似的方法用于获取并移除队首元素:poll() 和 remove()。它们的主要区别在于处理空队列的方式。poll() 是更安全的选择,当队列为空时会返回 null,不会中断程序流程,因此适用于生产环境中不确定队列状态的场景。而 remove() 则在队列为空时直接抛出 NoSuchElementException 异常,适用于你确信队列不为空的场合,用于快速暴露逻辑错误。例如:
Queue<String> queue = new LinkedList<>();
queue.offer("A");
queue.poll(); // 返回 "A"
queue.poll(); // 返回 null
queue.remove(); // 抛出 NoSuchElementException理解两者差异有助于编写更加健壮的队列操作逻辑。
27. ArrayDeque 与 LinkedList 有什么区别?
回答:
ArrayDeque 是基于数组实现的双端队列,性能更优;LinkedList 是基于链表实现,功能更丰富,但性能略逊一筹。
分析:
两者都实现了 Deque 接口,支持从两端插入与删除元素,常用于实现队列或栈。ArrayDeque 内部使用可变长数组,支持均摊 O(1) 的插入删除操作,但不允许插入 null 元素,其结构紧凑、缓存命中率高,适合作为栈或队列的高性能实现。LinkedList 则基于双向链表实现,支持插入 null,功能更灵活,能用于链式遍历、节点插入等复杂结构操作,但在内存占用和指针操作上略显冗余。此外,ArrayDeque 是在 JDK 1.6 引入的,相较之下更现代,避免了 Stack 的同步开销问题。在仅关注队列或栈性能的场景下,ArrayDeque 通常是首选。
28. 说一说 PriorityQueue
回答:
PriorityQueue 是一种基于优先级的队列,元素出队顺序由其优先级决定,而不是插入顺序。它内部使用最小堆实现,能高效完成优先级调度。
分析:
PriorityQueue 是 JDK 1.5 引入的高级队列实现,属于 Queue 接口的一个重要子类。与普通队列(FIFO)不同,PriorityQueue 会根据元素的优先级顺序来决定出队顺序——优先级高的元素会更早被移除。这一特性通过堆(heap)数据结构实现,默认使用小顶堆,即堆顶总是优先级最低(最小值)的元素。其底层由可扩展数组支持,通过元素的"上浮"与"下沉"操作,实现 O(log n) 的插入与删除效率。
默认情况下,元素必须实现 Comparable 接口,PriorityQueue 会根据 compareTo 结果进行自然排序;若构造时提供 Comparator 实例,则可自定义优先级规则。值得注意的是,PriorityQueue 不允许存储 null 元素,也不能添加彼此不可比较的对象,否则会在运行时抛出异常。此外,该类是非线程安全的,若在多线程环境中使用,应考虑通过外部同步或使用线程安全的并发队列(如 PriorityBlockingQueue)。
PriorityQueue 在面试与实战中常用于调度场景、任务优先级处理、Top K 问题、堆排序、图算法(如 Dijkstra)等,是一个典型的"基础数据结构 + 算法应用"结合体,掌握其原理和使用细节非常重要。