java Queue 详解

Java Queue 详解

Queue 是 Java 集合框架中用于实现 队列 数据结构的接口,位于 java.util 包中。队列是一种 先进先出(FIFO) 的数据结构,元素按照插入的顺序依次出队。


1. Queue 的基本特性

  1. FIFO(First-In-First-Out)

    • 队列中的第一个元素是最先被处理的。
    • 特殊实现(如 Deque)可以支持双向队列操作。
  2. 队列操作

    • 插入元素:add() / offer()
    • 访问元素(不移除):element() / peek()
    • 移除元素:remove() / poll()
  3. 接口定义
    Queue 是一个接口,继承自 java.util.Collection

  4. 实现类

    • LinkedList(常用)
    • PriorityQueue
    • ArrayDeque
    • ConcurrentLinkedQueue(线程安全)

2. Queue 的方法

Queue 接口提供了以下主要方法:

方法 描述
add(E e) 将指定元素插入队列,如果队列已满,则抛出异常。
offer(E e) 将指定元素插入队列,如果队列已满,则返回 false
remove() 移除并返回队列头部的元素,如果队列为空,则抛出异常。
poll() 移除并返回队列头部的元素,如果队列为空,则返回 null
element() 返回队列头部的元素(不移除),如果队列为空,则抛出异常。
peek() 返回队列头部的元素(不移除),如果队列为空,则返回 null

方法对比

方法类型 抛出异常 返回特殊值
插入 add() offer()
移除 remove() poll()
访问(不移除) element() peek()

3. Queue 的实现类

3.1 LinkedList

  • LinkedListQueue 的常用实现之一,底层基于链表实现。
  • 它既可以用作队列(FIFO),也可以用作双向队列(Deque)。
示例:
java 复制代码
import java.util.LinkedList;
import java.util.Queue;

public class LinkedListQueue {
    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<>();

        // 添加元素
        queue.add("A");
        queue.add("B");
        queue.add("C");

        // 访问头部元素
        System.out.println("Head: " + queue.peek()); // 输出:A

        // 移除元素
        System.out.println("Removed: " + queue.poll()); // 输出:A

        // 遍历队列
        for (String item : queue) {
            System.out.println(item); // 输出:B, C
        }
    }
}

3.2 PriorityQueue

  • 基于 堆(Heap) 实现的队列,元素按照自然顺序或自定义顺序排序。
  • 特点
    • 不保证 FIFO 顺序,优先级高的元素先出队。
    • 适合实现优先级任务调度。
示例:
java 复制代码
import java.util.PriorityQueue;

public class PriorityQueueExample {
    public static void main(String[] args) {
        PriorityQueue<Integer> pq = new PriorityQueue<>();

        // 添加元素
        pq.add(5);
        pq.add(2);
        pq.add(8);
        pq.add(1);

        // 按优先级移除元素
        while (!pq.isEmpty()) {
            System.out.println(pq.poll()); // 输出:1, 2, 5, 8
        }
    }
}

注意PriorityQueue 不支持 null 元素。


3.3 ArrayDeque

  • 基于 动态数组 实现的双端队列(Deque)。
  • 特点
    • LinkedList 更高效(无额外的链表节点开销)。
    • 可以用作栈(LIFO)或队列(FIFO)。
示例:
java 复制代码
import java.util.ArrayDeque;
import java.util.Queue;

public class ArrayDequeExample {
    public static void main(String[] args) {
        Queue<String> queue = new ArrayDeque<>();

        // 添加元素
        queue.offer("X");
        queue.offer("Y");
        queue.offer("Z");

        // 访问头部元素
        System.out.println("Head: " + queue.peek()); // 输出:X

        // 移除元素
        System.out.println("Removed: " + queue.poll()); // 输出:X
    }
}

3.4 ConcurrentLinkedQueue

  • 是一个线程安全的非阻塞队列,基于 CAS(Compare-And-Swap) 实现。
  • 适用场景
    • 适用于高并发场景下的无界队列。
示例:
java 复制代码
import java.util.concurrent.ConcurrentLinkedQueue;

public class ConcurrentQueueExample {
    public static void main(String[] args) {
        ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();

        // 添加元素
        queue.offer("P");
        queue.offer("Q");
        queue.offer("R");

        // 访问头部元素
        System.out.println("Head: " + queue.peek()); // 输出:P

        // 移除元素
        System.out.println("Removed: " + queue.poll()); // 输出:P
    }
}

4. 特殊队列

4.1 阻塞队列(BlockingQueue)

  • 提供阻塞操作的队列接口,位于 java.util.concurrent 包中。
  • 主要实现类
    • ArrayBlockingQueue:基于数组的有界阻塞队列。
    • LinkedBlockingQueue:基于链表的阻塞队列。
    • PriorityBlockingQueue:支持优先级排序的阻塞队列。
    • SynchronousQueue:一个没有存储能力的队列,直接在生产者和消费者之间传递数据。
示例:
java 复制代码
import java.util.concurrent.ArrayBlockingQueue;

public class BlockingQueueExample {
    public static void main(String[] args) throws InterruptedException {
        ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(3);

        // 添加元素
        queue.put("1");
        queue.put("2");
        queue.put("3");

        // 移除元素
        System.out.println(queue.take()); // 输出:1
    }
}

特点

  • 当队列满时,插入操作会阻塞。
  • 当队列空时,删除操作会阻塞。

4.2 双端队列(Deque)

  • Queue 的子接口,支持从两端插入和删除元素。
  • 常见实现:
    • ArrayDeque
    • LinkedList
示例:
java 复制代码
import java.util.Deque;
import java.util.LinkedList;

public class DequeExample {
    public static void main(String[] args) {
        Deque<String> deque = new LinkedList<>();

        // 添加元素
        deque.addFirst("A");
        deque.addLast("B");

        // 访问头尾元素
        System.out.println("First: " + deque.getFirst()); // 输出:A
        System.out.println("Last: " + deque.getLast());   // 输出:B

        // 移除元素
        deque.removeFirst();
        System.out.println("After removing first: " + deque);
    }
}

5. Queue 的常见用例

5.1 任务调度

  • 使用 PriorityQueueBlockingQueue 实现任务调度。

5.2 消息队列

  • 使用 ConcurrentLinkedQueueBlockingQueue 实现线程间通信。

5.3 树/图的广度优先搜索(BFS)

  • 使用 Queue 存储待访问的节点。
示例:
java 复制代码
import java.util.LinkedList;
import java.util.Queue;

public class BFSExample {
    public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<>();

        // 初始化队列
        queue.offer(1);

        while (!queue.isEmpty()) {
            int node = queue.poll();
            System.out.println("Visited node: " + node);
            // 模拟添加邻居节点
            if (node < 3) {
                queue.offer(node + 1);
            }
        }
    }
}

输出

Visited node: 1
Visited node: 2
Visited node: 3

6. 总结

常用实现类对比

实现类 特点 适用场景
LinkedList 基于链表,支持双端队列操作;性能适中。 一般队列操作或双向队列。
PriorityQueue 元素按优先级排序,不保证 FIFO 顺序。 优先级任务调度。
ArrayDeque 高效实现队列和栈;比 LinkedList 更节省内存。 双端队列或栈的实现。
ConcurrentLinkedQueue 线程安全的无界队列,适用于高并发场景。 多线程环境下的队列操作。
BlockingQueue 提供阻塞操作,用于线程间通信。 生产者-消费者模式。

选择 Queue 实现时,应根据具体需求(如是否需要优先级、线程安全等)选择合适的实现类。

相关推荐
The_Ticker4 分钟前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
大数据编程之光26 分钟前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
爪哇学长40 分钟前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
ExiFengs44 分钟前
实际项目Java1.8流处理, Optional常见用法
java·开发语言·spring
paj1234567891 小时前
JDK1.8新增特性
java·开发语言
繁依Fanyi1 小时前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
慧都小妮子1 小时前
Spire.PDF for .NET【页面设置】演示:打开 PDF 时自动显示书签或缩略图
java·pdf·.net
m51271 小时前
LinuxC语言
java·服务器·前端
IU宝1 小时前
C/C++内存管理
java·c语言·c++
瓜牛_gn1 小时前
依赖注入注解
java·后端·spring