Java中队列

队列是一种常见的数据结构,它按照先进先出(FIFO)的原则管理元素。在 Java 中,队列通常是通过链表或数组实现的,不同的实现类在内部数据结构和操作上可能有所不同。

1.原理

1.数据结构:队列的基本数据结构可以是链表或数组。链表实现的队列(如 LinkedList)允许高效地在两端进行添加和删除操作,而数组实现的队列(如 ArrayDeque)则可以更快地随机访问元素。
2.入队操作:将元素添加到队列的末尾称为入队操作。在链表实现中,入队操作涉及将新元素链接到链表的末尾;而在数组实现中,入队操作将新元素添加到数组的末尾,并更新队尾指针。
3.出队操作:从队列的头部移除元素称为出队操作。无论是链表还是数组实现,出队操作都涉及从队列的头部移除元素,并更新队头指针。
4.队列的大小:队列的大小可以根据添加和删除的元素数量来动态调整。在使用链表实现时,可以方便地添加或删除元素而不需要重新分配内存;而在使用数组实现时,可能需要进行数组扩容或缩小操作
在这里插入图片描述

2.实现

在这里插入图片描述

1.LinkedList

1.特点

1.双向链表结构: 每个元素都包含对其前一个元素和后一个元素的引用,这样可以轻松地在链表中插入和删除元素。
2.支持索引访问: 虽然链表的随机访问效率较低,但LinkedList仍然支持根据索引访问元素,可以使用get(int index)方法获取指定位置的元素。
3.支持头部和尾部操作: LinkedList实现了Deque接口,因此支持在头部和尾部添加、移除元素的操作,如offerFirst(E e)、offerLast(E e)、pollFirst()、pollLast()等。
4.非线程安全: LinkedList不是线程安全的,如果多个线程同时访问一个LinkedList实例并且至少有一个线程修改了列表的结构,那么必须通过外部同步来确保该LinkedList在并发环境中的安全性。
5.迭代器支持: LinkedList提供了ListIterator接口的实现,可以通过迭代器遍历链表中的元素。

2.常用方法

可以查看文档比较多
百度网盘 获取JDKAPI文档
链接:https://pan.baidu.com/s/1Z5mL0vVbXX1mMS8UqRaa6Q
提取码:2ktk
在这里插入图片描述

3.代码实现
LinkedList<String> linkedList = new LinkedList<>();// 添加元素到链表尾部
linkedList.add("A");
linkedList.add("B");
linkedList.add("C");// 在链表头部添加元素
linkedList.addFirst("X");// 在链表尾部添加元素
linkedList.addLast("Y");// 移除链表头部元素
linkedList.removeFirst();// 移除链表尾部元素
linkedList.removeLast();// 获取链表的第一个元素
String first = linkedList.getFirst();// 获取链表的最后一个元素
String last = linkedList.getLast();// 遍历链表元素
for (String element : linkedList) {System.out.println(element);
}

2.PriorityQueue

1.特点

1.基于堆实现: PriorityQueue通常基于堆数据结构实现,通常是一个最小堆(最小优先级队列),也可以通过提供自定义的比较器来创建最大堆(最大优先级队列)。
2.元素排序: 元素可以按照它们的自然顺序(如果它们实现了Comparable接口)或者根据提供的Comparator进行排序。
3.动态增长: PriorityQueue的大小可以动态增长,可以根据需要添加任意数量的元素。
4.不允许null元素: PriorityQueue不允许插入null元素,否则会抛出NullPointerException。
5.不是线程安全的: PriorityQueue不是线程安全的,如果多个线程同时访问一个PriorityQueue实例并且至少有一个线程修改了队列的结构,那么必须通过外部同步来确保该PriorityQueue在并发环境中的安全性。

2.常用方法

在这里插入图片描述

3.代码实现
// 创建一个最小堆(最小优先级队列)
PriorityQueue<Integer> minHeap = new PriorityQueue<>();// 添加元素到优先级队列
minHeap.offer(5);
minHeap.offer(3);
minHeap.offer(8);
minHeap.offer(1);// 获取并移除队列中的最小元素
int minElement = minHeap.poll();
System.out.println("最小元素:" + minElement);// 获取但不移除队列中的最小元素
int peekMinElement = minHeap.peek();
System.out.println("最小元素(但不移除):" + peekMinElement);// 创建一个最大堆(最大优先级队列),使用自定义比较器
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);// 添加元素到优先级队列
maxHeap.offer(5);
maxHeap.offer(3);
maxHeap.offer(8);
maxHeap.offer(1);// 获取并移除队列中的最大元素
int maxElement = maxHeap.poll();
System.out.println("最大元素:" + maxElement);

3.SynchronousQueue(多线程下安全)

1.特点

1.零容量:SynchronousQueue 是一个零容量的队列,它不保存任何元素。插入操作(offer)只有在有线程等待获取元素时才会成功,否则会一直阻塞。
2.直接传递:生产者线程通过 put 方法插入元素时会阻塞,直到有消费者线程调用 take 方法获取这个元素。这种机制可以实现直接传递数据,而不需要中间的缓冲区。
3.公平性:SynchronousQueue 可以选择是否公平地进行元素获取。在公平模式下,如果多个消费者线程同时等待获取元素,队列会按照线程等待的先后顺序来分配元素。
4.应用场景:适合用于生产者和消费者之间的直接传递数据的场景,例如线程池任务分配、消息传递等。

2.代码实现
BlockingQueue<Object> synchronousQueue = new SynchronousQueue<>();//同步队列
//添加元素
new Thread(()->{try {System.out.println(Thread.currentThread().getName() + "put 1");synchronousQueue.put(1);System.out.println(Thread.currentThread().getName() + "put 2");synchronousQueue.put(2);System.out.println(Thread.currentThread().getName() + "put 3");synchronousQueue.put(3);} catch (InterruptedException e) {throw new RuntimeException(e);}
},"线程A").start();//移除元素
new Thread(()->{try {TimeUnit.SECONDS.sleep(3);System.out.println(Thread.currentThread().getName() + "take" + synchronousQueue.take());TimeUnit.SECONDS.sleep(3);System.out.println(Thread.currentThread().getName() + "take" + synchronousQueue.take());TimeUnit.SECONDS.sleep(3);System.out.println(Thread.currentThread().getName() + "take" + synchronousQueue.take());} catch (InterruptedException e) {throw new RuntimeException(e);}
},"线程B").start();

3.BlockingQueue(阻塞队列)

多线程环境下,BlockingQueue通常用于实现生产者-消费者模式,其中生产者线程将数据放入队列,而消费者线程从队列中取出数据进行处理。
当队列为空时,消费者线程试图从队列中取出元素时会被阻塞,直到队列中有可用元素为止;而当队列已满时,生产者线程试图向队列中放入元素时也会被阻塞,直到队列有空闲位置为止。

1.常用实现

1.ArrayBlockingQueue: 基于数组实现的有界阻塞队列,必须指定队列的容量,适合固定大小的线程池。
2.LinkedBlockingQueue: 基于链表实现的可选有界或无界阻塞队列,默认情况下是无界的,但也可以指定容量创建有界队列。
3.PriorityBlockingQueue: 是一个支持优先级排序的无界阻塞队列,元素按照它们的自然顺序或者根据提供的Comparator进行排序。
4.DelayQueue: 是一个支持延迟元素的无界阻塞队列,其中的元素只有在其指定的延迟时间到达后才能被获取。
5.SynchronousQueue: 是一个不存储元素的阻塞队列,每个插入操作必须等待另一个线程进行相应的删除操作,适合传递性场景。

2.常用方法

1.put(E e): 将指定的元素插入到队列中,如果队列已满,则阻塞直到队列有空闲位置。
2.take(): 获取并移除队列的头部元素,如果队列为空,则阻塞直到队列中有可用元素。
3.offer(E e, long timeout, TimeUnit unit): 将指定的元素插入到队列中,如果队列已满,则阻塞直到指定的超时时间。
4.poll(long timeout, TimeUnit unit): 获取并移除队列的头部元素,如果队列为空,则阻塞直到指定的超时时间。
5.remainingCapacity(): 返回队列中剩余的可用空间。

3.四组API

1.抛出异常
BlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
//添加元素
System.out.println(blockingQueue.add("AAAA"));
System.out.println(blockingQueue.add("BBBB"));
System.out.println(blockingQueue.add("CCCC"));//获取队列首位元素
System.out.println(blockingQueue.element());//打印元素
blockingQueue.stream().forEach(System.out::print);System.out.println();
//抛出异常:java.lang.IllegalStateException: Queue full
// blockingQueue.add("DDDD");//移除元素
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.element());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());blockingQueue.stream().forEach(System.out::print);
//抛出异常:java.util.NoSuchElementException
System.out.println(blockingQueue.element());//抛出异常:java.util.NoSuchElementException
// System.out.println(blockingQueue.remove());
2.不抛出异常
BlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
//添加元素
System.out.println(blockingQueue.offer("AAAA"));
System.out.println(blockingQueue.offer("BBBB"));
System.out.println(blockingQueue.offer("CCCC"));//检测队首元素
System.out.println(blockingQueue.peek());//打印元素
blockingQueue.stream().forEach(System.out::print);System.out.println();//不抛出异常 返回 false
// System.out.println(blockingQueue.offer("DDDD"));System.out.println(blockingQueue.poll());
//检测队首元素
System.out.println(blockingQueue.peek());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());//打印元素
blockingQueue.stream().forEach(System.out::print);System.out.println();//检测队首元素 null 无异常
System.out.println(blockingQueue.peek());
//null 不抛出异常
// System.out.println(blockingQueue.poll());
3.阻塞等待
BlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
//添加元素
blockingQueue.put("AAAA");
blockingQueue.put("BBBB");
blockingQueue.put("CCCC");//打印元素
blockingQueue.stream().forEach(System.out::print);System.out.println();//阻塞线程执行,直到元素能够添加进去
// blockingQueue.put("DDDD");System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
//阻塞线程执行,直到能够消费到元素
System.out.println(blockingQueue.take());
4.超时等待
BlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
//添加元素
System.out.println(blockingQueue.offer("AAAA"));
System.out.println(blockingQueue.offer("BBBB"));
System.out.println(blockingQueue.offer("CCCC"));//检测队首元素
System.out.println(blockingQueue.peek());//打印元素
blockingQueue.stream().forEach(System.out::print);System.out.println();//不抛出异常 等待超过两秒 返回 false
System.out.println(blockingQueue.offer("DDDD",2,TimeUnit.SECONDS));System.out.println(blockingQueue.poll());
//检测队首元素
System.out.println(blockingQueue.peek());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());//打印元素
blockingQueue.stream().forEach(System.out::print);System.out.println();//检测队首元素 null 无异常
System.out.println(blockingQueue.peek());
//null 不抛出异常 超过两秒System.out.println(blockingQueue.poll(2,TimeUnit.SECONDS));
5.图示四组API

在这里插入图片描述
不足之处,望海涵!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/610775.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【网站项目】学生选课系统小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

el-tree基础渲染

el-tree 每个节点左右布局鼠标经过接电视&#xff0c;左边文字变色&#xff0c;右边不变 <el-tree:data"list":props"defaultProps"default-expand-all:expand-on-click-node"false"><template #default"{ data }"><e…

个人劳保用品穿戴检测系统 安全帽、工服、面罩、防护手套、防护鞋、安全背带穿戴检测等

背景 在工业生产、医疗护理、消防救援等高风险领域&#xff0c;正确穿戴个人防护装备或劳保用品&#xff08;PPE&#xff1a;Personal Protective Equipment&#xff09;是保障人员安全的重要措施&#xff0c;如安全帽、反光衣、安全背带等。然而&#xff0c;现实中往往会出现…

ubuntu系统安装python虚拟环境

一、安装python&#xff1a; 步骤1&#xff1a;在Ubuntu系统中打开终端&#xff0c;你可以使用快捷键CtrlAltT来打开终端&#xff0c;或者在应用程序菜单中找到终端。 步骤2&#xff1a;更新软件包列表&#xff0c;在终端中输入以下命令&#xff0c;更新软件包列表&#xff1…

MacOS安装openMP报错【已解决】

error: Target “WLBG” links to: OpenMP::OpenMP_CXX but the target was not found. Possible reasons include: * There is a typo in the target name. * A find_package call is missing for an IMPORTED target. * An ALIAS target is missing. 最开始是报这个错&#x…

vue3页面导出为PDF文件

vue3页面导出为PDF文件 尝试了很多方法&#xff0c;都没有找到完美的解决方法 目前网上有个思路&#xff0c;就是将页面先转存为图片&#xff0c;然后将图片另存为PDF文件 记录一下完整过程 一、安装必备包 安装两个第三方插件 npm i html2canvas npm i jspdfhtml2canvas…

Meta宣布全新训推一体加速器:完全集成PyTorch 2,性能3倍提升

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 Meta 疯狂砸入数十亿美元&#xff0c;一部分招揽人才&#xff0c;一部分造芯片。 Meta 正在不…

Redis 主从复制实现

Redis 主从复制实现 第一次同步命令传播分摊主服务器的压力增量复制 第一次同步 第一阶段&#xff1a;建立链接、协商同步(为全量复制做准备) 执行了 replicaof 命令后&#xff0c;从服务器就会给主服务器发送 psync 命令&#xff0c;表示要进行数据同步。psync 命令包含两个参…

Java List基础篇

目录 前言一、常用List1.1 List1.1.1 特点1.1.2 常用API 1.2 ArrayList1.2.1 特点1.2.2 使用 1.3 LinkedList1.3.1 特点1.3.2 使用 1.4 CopyOnWriteArrayList1.4.1 特点1.4.2 使用 1.5 Arrays.asList()1.5.1 特点1.5.2 使用 二、对比总结 前言 一、常用List 1.1 List List是…

贪心算法:排列算式

题目描述 给出n数字&#xff0c;对于这些数字是否存在一种计算顺序&#xff0c;使得计算过程中数字不会超过3也不会小于0&#xff1f; 输入描述: 首行给出一个正整数t,(1≤t≤1000)代表测试数据组数每组测试数据第一行一个正整数n,(1≤n≤500)第二行包含n个以空格分隔的数字…

基于python的天气数据可视化系统、Flask框架,爬虫采集天气数据,可视化分析

系统介绍 基于Python的天气预测可视化分析系统&#xff0c;该项目的主要流程和功能包括&#xff1a; 数据获取&#xff1a; 使用Python的pandas库从2345天气网&#xff08;http://tianqi.2345.com/Pc/GetHistory&#xff09;抓取山东省各市区县在2021年至2023年间的天气历史数…

实况窗助力美团打造鸿蒙原生外卖新体验,用户可实时掌握外卖进展

自2023年华为宣布全新HarmonyOS NEXT蓄势待发&#xff0c;鸿蒙原生应用全面启动以来&#xff0c;已有金融、旅行、社交等多个领域的企业和开发者陆续宣布加入鸿蒙生态。其中&#xff0c;美团作为国内头部的科技零售企业&#xff0c;是首批加入鸿蒙生态的伙伴&#xff0c;其下的…