news 2025/12/25 7:04:56

Java集合-Queue讲解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java集合-Queue讲解

目录

  • 一、集合框架层次结构
  • 二、Collection集合
    • 1、Queue队列
      • 1. LinkedList 作为队列
      • 2. ArrayDeque 作为队列
      • 3. PriorityQueue 优先队列
      • 4.LinkedBlockingQueue - 最常用的阻塞队列
      • 5. ConcurrentLinkedQueue - 高并发非阻塞队列
    • 2、队列操作模式对比
      • 1.插入操作对比
      • 2.移除操作对比
      • 3.查看操作对比
    • 3、队列选择

Java 集合框架(Collections Framework)是 Java 中用于存储和操作数据组的重要架构。它提供了一组接口、实现类和算法。

一、集合框架层次结构

Collection (接口) ├── List (接口 - 有序,可重复) │ ├── ArrayList (实现类) │ ├── LinkedList (实现类) │ ├── Vector (线程安全,已过时) │ └── Stack (继承Vector) │ ├── Set (接口 - 无序,不可重复) │ ├── HashSet (实现类) │ │ └── LinkedHashSet (保持插入顺序) │ ├── SortedSet (接口) │ │ └── TreeSet (实现类) │ └── EnumSet (专用于枚举) │ └── Queue (接口 - 队列) ├── Deque (双端队列接口) │ ├── ArrayDeque (实现类) │ └── LinkedList (也实现了Deque) │ ├── PriorityQueue (优先队列) └── BlockingQueue (阻塞队列接口) ├── ArrayBlockingQueue ├── LinkedBlockingQueue └── PriorityBlockingQueue Map (接口 - 键值对) ├── HashMap (实现类) │ └── LinkedHashMap (保持插入顺序) ├── TreeMap (基于红黑树) ├── Hashtable (线程安全,已过时) ├── WeakHashMap (弱引用) └── ConcurrentHashMap (并发版)

Java集合大致可以分为两大体系,一个是Collection,另一个是Map

  • Collection:主要由ListSetQueue接口组成,List代表有序、重复的集合;其中Set代表无序、不可重复的集合;Queue体系集合,代表一种队列集合实现。
  • Map:则代表具有映射关系的键值对集合。
    java.util.Collection下的接口和继承类关系简易结构图:

    java.util.Map下的接口和继承类关系简易结构图:


其中,Java 集合框架中主要封装的是典型的数据结构和算法,如动态数组、双向链表、队列、栈、Set、Map等。

二、Collection集合

通过集合的关系图我们可以知道Collection是集合的顶层父类,他定义了集合的基本方法如

基本操作方法

方法签名功能描述返回值示例时间复杂度
int size()返回集合中元素的数量元素个数list.size()3O(1)
boolean isEmpty()判断集合是否为空true/falselist.isEmpty()falseO(1)
boolean contains(Object o)判断是否包含指定元素true/falselist.contains("A")trueList: O(n)
Set: O(1)
TreeSet: O(log n)
boolean add(E e)添加元素到集合是否成功list.add("D")trueArrayList: 均摊O(1)
LinkedList: O(1)
TreeSet: O(log n)
boolean remove(Object o)移除指定元素是否成功list.remove("A")trueArrayList: O(n)
LinkedList: O(n)
HashSet: O(1)

批量操作方法

方法签名功能描述返回值示例说明
boolean containsAll(Collection<?> c)是否包含集合c中所有元素true/falselist.containsAll(subList)检查子集关系
boolean addAll(Collection<? extends E> c)添加集合c中所有元素是否改变list.addAll(anotherList)批量添加
boolean removeAll(Collection<?> c)移除集合c中所有元素是否改变list.removeAll(toRemove)差集操作
boolean retainAll(Collection<?> c)仅保留集合c中元素是否改变list.retainAll(common)交集操作
void clear()清空集合所有元素list.clear()集合变为空

转换和迭代方法

方法签名功能描述返回值示例说明
Object[] toArray()转换为Object数组Object数组list.toArray()返回新数组
<T> T[] toArray(T[] a)转换为指定类型数组指定类型数组list.toArray(new String[0])类型安全转换
Iterator<E> iterator()返回迭代器Iterator对象list.iterator()用于遍历集合
default boolean removeIf(Predicate<? super E> filter)条件删除是否改变list.removeIf(s -> s.length() > 3)Java 8+
default Spliterator<E> spliterator()返回分割迭代器Spliterator对象list.spliterator()Java 8+,并行遍历
default Stream<E> stream()返回顺序流Stream对象list.stream()Java 8+,流操作
default Stream<E> parallelStream()返回并行流Stream对象list.parallelStream()Java 8+,并行流操作

集合运算方法

方法数学运算示意图示例
addAll()并集A ∪ BA.addAll(B)
retainAll()交集A ∩ BA.retainAll(B)
removeAll()差集A - BA.removeAll(B)

常见操作示例

操作需求代码示例说明
遍历集合for (E e : collection) { ... }增强for循环
安全遍历并删除iterator.remove()使用迭代器删除
转换为数组String[] arr = coll.toArray(new String[0])推荐写法
批量添加元素coll.addAll(Arrays.asList("A","B","C"))初始化集合
过滤集合coll.removeIf(e -> e.startsWith("A"))Java 8+
集合判空if (!coll.isEmpty()) { ... }优于size() > 0

注意事项表格

方法注意事项推荐做法
contains()依赖equals()hashCode()正确实现这两个方法
remove(Object)只删除第一个匹配项使用removeIf()删除所有
toArray()无参方法返回Object[]使用带参方法指定类型
addAll()可能修改原集合注意并发修改异常
clear()不释放元素引用大集合考虑设为null
iterator()遍历时不能修改集合使用迭代器的remove()
场景建议理由
频繁包含检查使用HashSetO(1)时间复杂度
频繁插入删除使用LinkedList首尾操作O(1)
随机访问使用ArrayListO(1)索引访问
需要排序使用TreeSet自动维护顺序
线程安全使用并发集合ConcurrentHashMap
只读操作使用不可变集合Collections.unmodifiableXXX()

Collection集合中所包含的方法:

publicinterfaceCollection<E>extendsIterable<E>{// 基本操作方法intsize();booleanisEmpty();booleancontains(Objecto);booleanadd(Ee);booleanremove(Objecto);// 批量操作booleancontainsAll(Collection<?>c);booleanaddAll(Collection<?extendsE>c);booleanremoveAll(Collection<?>c);booleanretainAll(Collection<?>c);voidclear();// 数组转换Object[]toArray();<T>T[]toArray(T[]a);// 迭代器Iterator<E>iterator();// Java 8 新增方法defaultbooleanremoveIf(Predicate<?superE>filter){...}defaultSpliterator<E>spliterator(){...}defaultStream<E>stream(){...}defaultStream<E>parallelStream(){...}}

1、Queue队列

核心概念
Queue是 Java 集合框架中表示先进先出(FIFO)队列的接口,支持在队尾插入元素,在队头移除元素。
Queue 接口结构

publicinterfaceQueue<E>extendsCollection<E>{// 插入元素booleanadd(Ee);// 添加失败抛异常booleanoffer(Ee);// 添加失败返回false// 移除元素Eremove();// 移除失败抛异常Epoll();// 移除失败返回null// 查看元素(不移除)Eelement();// 查看失败抛异常Epeek();// 查看失败返回null}

Queue 实现类对比

实现类底层结构线程安全特性使用场景
LinkedList双向链表❌ 否也可作List、Deque一般队列
ArrayDeque循环数组❌ 否高性能双端队列推荐的单端队列
PriorityQueue二叉堆❌ 否优先级队列任务调度
ArrayBlockingQueue数组✅ 是有界阻塞队列生产者-消费者
LinkedBlockingQueue链表✅ 是可选有界阻塞队列高并发队列
ConcurrentLinkedQueue链表✅ 是无锁队列高并发非阻塞
PriorityBlockingQueue二叉堆✅ 是阻塞优先队列优先级任务调度
DelayQueuePriorityQueue✅ 是延迟队列定时任务
SynchronousQueue无存储✅ 是直接传递队列线程间直接传递

1. LinkedList 作为队列

基本使用

// LinkedList 实现了 Queue 接口Queue<String>queue=newLinkedList<>();// 入队queue.offer("A");// 推荐使用 offer()queue.add("B");// 也可以使用 add()queue.offer("C");System.out.println(queue);// [A, B, C]// 查看队头Stringhead=queue.peek();// "A"(不移除)System.out.println("队头: "+head);// ASystem.out.println(queue);// [A, B, C](不变)// 出队Stringremoved1=queue.poll();// "A"Stringremoved2=queue.remove();// "B"(队列空时抛异常)System.out.println("出队后: "+queue);// [C]// 判断队列状态booleanisEmpty=queue.isEmpty();// falseintsize=queue.size();// 1

特点

  • 基于双向链表实现
  • 可作队列、双端队列、列表使用
  • 插入删除 O(1),查找 O(n)
  • 非线程安全

使用场景

  • 普通队列需求:消息队列、任务队列、等待队列
  • 需要同时用到队列和列表功能
  • 单线程环境或手动同步的多线程环境

2. ArrayDeque 作为队列

基本使用

// ArrayDeque 性能优于 LinkedListQueue<Integer>queue=newArrayDeque<>(10);// 指定初始容量// 入队for(inti=1;i<=5;i++){queue.offer(i);}// 遍历队列(不影响队列)System.out.print("队列元素: ");for(Integernum:queue){System.out.print(num+" ");// 1 2 3 4 5}System.out.println();// 批量出队while(!queue.isEmpty()){Integernum=queue.poll();System.out.println("处理: "+num);}

特点

  • 基于循环数组实现
  • 性能比 LinkedList 好(内存连续)
  • 初始容量为 16,自动扩容为 2 倍
  • 推荐的单端队列实现

使用场景

  • 高性能要求:游戏服务器、高频交易系统
  • 已知容量上限:可以预分配合适大小
  • 替代Stack:使用ArrayDeque作为栈(push(), pop()

3. PriorityQueue 优先队列

基本使用

// 默认最小堆(小顶堆)Queue<Integer>pq=newPriorityQueue<>();// 添加元素pq.offer(5);pq.offer(1);pq.offer(3);pq.offer(8);pq.offer(2);// 按优先级出队(从小到大)while(!pq.isEmpty()){System.out.print(pq.poll()+" ");// 1 2 3 5 8}System.out.println();// 最大堆(大顶堆)Queue<Integer>maxHeap=newPriorityQueue<>(Comparator.reverseOrder());maxHeap.offer(5);maxHeap.offer(1);maxHeap.offer(3);while(!maxHeap.isEmpty()){System.out.print(maxHeap.poll()+" ");// 5 3 1}

自定义排序

// 自定义对象优先队列classTaskimplementsComparable<Task>{Stringname;intpriority;// 数字越小优先级越高publicTask(Stringname,intpriority){this.name=name;this.priority=priority;}@OverridepublicintcompareTo(Taskother){returnInteger.compare(this.priority,other.priority);}@OverridepublicStringtoString(){returnname+"("+priority+")";}}Queue<Task>taskQueue=newPriorityQueue<>();taskQueue.offer(newTask("邮件",3));taskQueue.offer(newTask("电话",1));taskQueue.offer(newTask("会议",2));while(!taskQueue.isEmpty()){System.out.println(taskQueue.poll());// 电话(1) -> 会议(2) -> 邮件(3)}

使用场景

  • 任务调度:操作系统进程调度
  • 医院急诊:按病情严重程度
  • VIP服务:按会员等级
  • 股票交易:按价格优先级

4.LinkedBlockingQueue - 最常用的阻塞队列

// 无界或有界阻塞队列BlockingQueue<Integer>queue=newLinkedBlockingQueue<>();// 无界BlockingQueue<Integer>boundedQueue=newLinkedBlockingQueue<>(100);// 有界// 生产者-消费者模式classProducerConsumer{privatefinalBlockingQueue<Integer>queue=newLinkedBlockingQueue<>(10);// 生产者classProducerimplementsRunnable{publicvoidrun(){try{for(inti=0;i<20;i++){queue.put(i);System.out.println("生产: "+i);Thread.sleep(100);}}catch(InterruptedExceptione){Thread.currentThread().interrupt();}}}// 消费者classConsumerimplementsRunnable{publicvoidrun(){try{while(true){Integeritem=queue.take();System.out.println("消费: "+item);Thread.sleep(150);}}catch(InterruptedExceptione){Thread.currentThread().interrupt();}}}}

使用场景

  • 线程池任务队列ThreadPoolExecutor默认使用
  • 消息中间件KafkaRocketMQ的生产者-消费者
  • 日志处理:多个应用写日志,一个线程消费日志
  • 数据缓冲:生产速度 > 消费速度时的缓冲

5. ConcurrentLinkedQueue - 高并发非阻塞队列

// 非阻塞并发队列ConcurrentLinkedQueue<String>concurrentQueue=newConcurrentLinkedQueue<>();// 多线程并发操作List<Thread>threads=newArrayList<>();// 生产者线程for(inti=0;i<5;i++){Threadproducer=newThread(()->{for(intj=0;j<10;j++){concurrentQueue.offer(Thread.currentThread().getName()+"-"+j);}});threads.add(producer);}// 消费者线程for(inti=0;i<3;i++){Threadconsumer=newThread(()->{while(!concurrentQueue.isEmpty()){Stringitem=concurrentQueue.poll();if(item!=null){System.out.println(Thread.currentThread().getName()+" 消费: "+item);}}});threads.add(consumer);}// 启动所有线程threads.forEach(Thread::start);threads.forEach(t->{try{t.join();}catch(InterruptedExceptione){}});System.out.println("最终队列大小: "+concurrentQueue.size());

使用场景

  • 实时日志收集:多个服务同时写日志
  • 股票行情推送:高频行情数据
  • 在线游戏:玩家动作队列
  • 点击流分析:用户行为跟踪

2、队列操作模式对比

1.插入操作对比

Queue<String>queue=newLinkedList<>();// 插入方法对比queue.add("A");// 成功返回true,失败抛IllegalStateExceptionqueue.offer("B");// 成功返回true,失败返回false// 使用建议:// 1. 有界队列或不确定时用 offer()// 2. 确定不会失败时用 add()

2.移除操作对比

Queue<String>queue=newLinkedList<>();queue.offer("A");// 移除方法对比Stringelem1=queue.remove();// 返回"A",队列空时抛NoSuchElementExceptionStringelem2=queue.poll();// 队列空时返回null// 使用建议:// 1. 需要处理空队列时用 poll()// 2. 确定队列不空时用 remove()

3.查看操作对比

Queue<String>queue=newLinkedList<>();queue.offer("A");// 查看方法对比Stringhead1=queue.element();// 返回"A",队列空时抛NoSuchElementExceptionStringhead2=queue.peek();// 队列空时返回null// 使用建议:// 1. 需要处理空队列时用 peek()// 2. 确定队列不空时用 element()

3、队列选择

队列一句话总结使用建议
LinkedList“什么都能干,但什么都不精”需要同时用到队列和列表功能时
ArrayDeque“单线程下的性能冠军”替代 LinkedList,性能要求高时
PriorityQueue“VIP优先通道”需要按优先级处理时
LinkedBlockingQueue“生产者和消费者的桥梁”多线程协作,生产者-消费者模式
ConcurrentLinkedQueue“高并发下的无锁战士”超高并发,读多写多场景
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2025/12/16 16:59:24

LobeChat能否用于构建AI绘画助手?多模态支持前景展望

LobeChat 能否用于构建 AI 绘画助手&#xff1f;多模态支持前景展望 在生成式 AI 浪潮席卷创意产业的今天&#xff0c;越来越多的设计师、内容创作者甚至普通用户开始期待一种更自然、更直观的人机协作方式——用对话来“指挥”AI 完成图像创作。想象这样一个场景&#xff1a;你…

作者头像 李华
网站建设 2025/12/16 16:59:06

PaddlePaddle高性能推理引擎Paddle Inference安装与测试

Paddle Inference&#xff1a;从安装到实战的高性能推理引擎深度实践 在AI模型日益复杂、部署场景愈发多样的今天&#xff0c;一个常见的现实是&#xff1a;模型训练得再好&#xff0c;如果推理慢、资源占用高、部署困难&#xff0c;依然无法真正落地。尤其是在金融交易实时风控…

作者头像 李华
网站建设 2025/12/16 16:58:41

第二章(2.5):微控制器8051的硬件结构---时钟、复位和MCU工作方式

时钟电路与时序微控制器的时钟为CPU和各个功能模块的协调工作提供同步信号和基本时序信号。时钟电路经典8051MCU必须通过外接晶振、电容&#xff0c;与内部时钟电路构成时钟发生器来产生MCU工作需要的信号&#xff0c;如下图所示。晶振频率范围一般为1.2MHz~12MHz&#xff0c;常…

作者头像 李华
网站建设 2025/12/16 16:58:33

Spring Bean 的生命周期详解

Spring Bean 的生命周期是指从 Bean 被 Spring 容器创建、初始化、使用到销毁的整个过程。理解这一过程,能帮助你精准控制 Bean 的行为(如自定义初始化逻辑、资源释放),也是解决 Spring 容器相关问题的核心基础。 Spring Bean 的生命周期可分为核心流程和扩展流程,核心流…

作者头像 李华
网站建设 2025/12/16 16:58:02

Dify+视觉模型实现文生视频工作流

Dify 视觉模型实现文生视频工作流 在短视频内容爆发的今天&#xff0c;从一段文字自动生成一段生动的视频&#xff0c;已经不再是科幻电影中的桥段。越来越多的企业和创作者开始探索“文本生成视频”&#xff08;Text-to-Video&#xff09;的技术路径&#xff0c;但传统方式往…

作者头像 李华