Java并发基础:Deque接口和Queue接口的区别?

Java并发基础:Deque接口和Queue接口的区别? - 程序员古德

核心概念

Deque(double ended queue,双端队列)和Queue(队列)都是Java集合框架中的接口,它们用于处理元素的排队和出队,但是它们之间存在一些重要的区别,如下:

1、Queue接口

Queue接口代表一个先进先出(FIFO)的队列,只能从一端添加元素,并从另一端移除元素,因此,可以使用add()offer()方法将元素添加到队列的末尾,使用remove()poll()方法从队列的头部移除元素,如果尝试从一个空的队列中移除元素,remove()方法会抛出NoSuchElementException,而poll()方法则会返回null

2、Deque接口

Deque接口,即双端队列,允许从两端添加或者移除元素,它提供了两套添加和移除元素的方法,一套在队列的头部操作,另一套在队列的尾部操作,因此Deque就可以当作队列(FIFO)或者栈(LIFO)来使用,对于Deque,可以在队列头部使用addFirst()offerFirst()添加元素,使用removeFirst()pollFirst()移除元素;在队列尾部使用addLast()offerLast()添加元素,使用removeLast()pollLast()移除元素,如果尝试从一个空的双端队列中移除元素,那么相关的removeXXX()方法同样会抛出NoSuchElementException,而pollXXX()方法会返回null

Queue接口和Deque接口的主要区别在于,Queue接口仅支持在一端添加元素,在另一端移除元素,而Deque接口则支持在两端都进行添加和移除元素的操作,另外,Deque接口的功能更强大,因为它可以当作队列、栈或者双端队列来使用,而Queue接口只能当作队列来使用。

代码案例

Java并发基础:Deque接口和Queue接口的区别? - 程序员古德

Deque

Deque接口代表一个双端队列(double-ended queue),双端队列是一个具有队列和栈的性质的数据结构,它允许元素从两端插入和删除,因此可以在队列的前面(头部)或后面(尾部)添加或移除元素,它的主要功能包括:

1、添加元素:

  1. addFirst(E e) / offerFirst(E e):在队列的头部插入元素,如果队列已满,addFirst会抛出IllegalStateException,而offerFirst则返回false
  2. addLast(E e) / offerLast(E e):在队列的尾部插入元素,如果队列已满,addLast会抛出IllegalStateException,而offerLast则返回false

2、移除元素:

  1. removeFirst() / pollFirst():从队列的头部移除并返回元素,如果队列为空,removeFirst会抛出NoSuchElementException,而pollFirst则返回null
  2. removeLast() / pollLast():从队列的尾部移除并返回元素,如果队列为空,removeLast会抛出NoSuchElementException,而pollLast则返回null

3、检查元素

  1. getFirst() / peekFirst():获取但不移除队列头部的元素,如果队列为空,getFirst会抛出NoSuchElementException,而peekFirst则返回null
  2. getLast() / peekLast():获取但不移除队列尾部的元素,如果队列为空,getLast会抛出NoSuchElementException,而peekLast则返回null

Deque接口的使用场景非常广泛,主要包括如下:

  1. 当需要一个可以作为队列(FIFO)或栈(LIFO)使用的数据结构时。
  2. 在需要高效地在两端添加或移除元素的场景中,如实现撤销/重做功能、缓冲区管理等。
  3. 作为其他数据结构的底层实现,如实现一个自定义的栈或队列。

下面是一个简单的代码示例,展示了如何使用Deque接口,如下代码:

import java.util.Deque;  
import java.util.LinkedList;  public class DequeExample {  public static void main(String[] args) {  Deque<String> deque = new LinkedList<>();  // 在队列头部添加元素  deque.addFirst("Element 1 (Head)");  // 在队列尾部添加元素  deque.addLast("Element 2 (Tail)");  // 在队列头部继续添加元素  deque.offerFirst("Element 0 (Head)");  // 打印队列元素  System.out.println("Deque contents: " + deque);  // 从队列头部移除并返回元素  String removedElement = deque.pollFirst();  System.out.println("Removed element from head: " + removedElement);  // 从队列尾部移除并返回元素  removedElement = deque.pollLast();  System.out.println("Removed element from tail: " + removedElement);  // 检查队列头部元素而不移除  String headElement = deque.peekFirst();  System.out.println("Head element: " + headElement);  // 检查队列是否为空  System.out.println("Deque is empty? " + deque.isEmpty());  }  
}

输出将会是:

Deque contents: [Element 0 (Head), Element 1 (Head), Element 2 (Tail)]  
Removed element from head: Element 0 (Head)  
Removed element from tail: Element 2 (Tail)  
Head element: Element 1 (Head)  
Deque is empty? false

在上面代码中,使用了LinkedList类作为Deque接口的实现,因为LinkedList类实现了Deque接口,因此它提供了双端队列的所有操作,向队列中添加了一些元素,然后从头部和尾部移除它们,并检查了队列的头部元素和是否为空。

Queue

代表一个队列数据结构,即一种特殊的线性表,只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,这种操作规则也被称为“先进先出”(FIFO,First-In-First-Out),它的主要功能包括:

1、插入元素:

  1. add(E e):将指定的元素插入此队列中(如果立即可行且不会违反容量限制),成功时返回 true,如果当前没有可用的空间,则抛出 IllegalStateException,不过,在 Queue 接口的实现中,这个方法通常不会抛出异常,因为大多数队列实现都是有界的,但这个界限通常很大。
  2. offer(E e):将指定的元素插入此队列中(如果立即可行且不会违反容量限制),成功时返回 true,如果当前没有可用的空间,则返回 false

2、移除元素

  1. remove():移除并返回此队列的头部,如果此队列为空,则抛出 NoSuchElementException
  2. poll():移除并返回此队列的头部,或返回 null 如果此队列为空。

3、检查元素

  1. element():检索,但不移除此队列的头部,如果此队列为空,则抛出 NoSuchElementException
  2. peek():检索,但不移除此队列的头部,或返回 null 如果此队列为空。

使用场景

  • 缓冲:当数据需要以有序的方式处理,但又不需要立即处理所有数据时,队列作为缓冲很有用,例如,打印任务队列,网络请求队列等。
  • 生产者-消费者问题:队列经常用于协调多个线程之间的合作,尤其是在生产者-消费者场景中,生产者将产品放入队列,而消费者从队列中取出产品进行消费。
  • 广度优先搜索:在图论中,队列用于实现广度优先搜索(BFS)算法。
  • 事件驱动的系统:队列可以用于存储待处理的事件,例如用户界面事件或系统事件。

代码示例

下面是一个简单的 Queue 接口使用示例,使用了 LinkedList 类作为实现,如下代码:

import java.util.LinkedList;  
import java.util.Queue;  public class QueueExample {  public static void main(String[] args) {  Queue<String> queue = new LinkedList<>();  // 插入元素  queue.offer("Apple");  queue.offer("Banana");  queue.offer("Cherry");  System.out.println("Initial Queue: " + queue);  // 移除元素  String removedElement = queue.poll();  System.out.println("Removed Element: " + removedElement);  System.out.println("Queue after removal: " + queue);  // 检查元素  String headElement = queue.peek();  System.out.println("Head of the Queue: " + headElement);  // 遍历队列  System.out.println("Iterating over the queue:");  for (String fruit : queue) {  System.out.println(fruit);  }  }  
}

输出:

Initial Queue: [Apple, Banana, Cherry]  
Removed Element: Apple  
Queue after removal: [Banana, Cherry]  
Head of the Queue: Banana  
Iterating over the queue:  
Banana  
Cherry

在这个示例中,创建了一个 Queue,使用 offer 方法插入了几个元素,使用 poll 方法移除了队列的头部元素,并使用 peek 方法来查看当前队列的头部元素,最后,使用增强for循环遍历了队列中的所有元素。

关注我,每天学习互联网编程技术 - 程序员古德

END!

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

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

相关文章

idea: 无法创建Java Class文件(SpringBoot)已解决

第一&#xff1a;点击file-->project Sructure... 第二步&#xff1a;点击Moudules 选择自己需要创建java的文件夹&#xff08;我这里选择的是main&#xff09;右键点击Sources&#xff0c;然后点击OK即可 然后就可以创建java类了

Python算法题集_两数相加

Python算法题集_两数相加 题2&#xff1a;两数相加1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【直接相加】2) 改进版一【对齐链表】3) 改进版二【数组求和】 4. 最优算法 本文为Python算法题集之一的代码示例 题2&#xff1a;两数相加 1.…

Spring Authorization Server Spring Security密码加密

文章目录 一、修改密码编码器二、效果三、注意点1. RegisteredClient2. UserDetailsService 一、修改密码编码器 以BCryptPasswordEncoder举例。 直接将其注册成PasswordEncoder 的Bean即可。 Beanpublic PasswordEncoder passwordEncoder() {// 密码为明文方式 // ret…

创建本地yum源并安装tree命令(openEuler-20.03-LTS-SP3)

步骤 1&#xff1a;下载ISO镜像 首先&#xff0c;您需要从提供的URL下载ISO镜像文件&#xff1a; cd /opt wget https://mirrors.dotsrc.org/openeuler/openEuler-20.03-LTS-SP3/ISO/x86_64/openEuler-20.03-LTS-SP3-x86_64-dvd.iso步骤 2&#xff1a;挂载ISO镜像 接下来&am…

DMA直接内存访问,STM32实现高速数据传输使用配置

1、DMA运用场景 随着智能化、信息化的不断推进&#xff0c;嵌入式设备的数据处理量也呈现指数级增加&#xff0c;因此对于巨大的数据量处理的情况时&#xff0c;必须采取其它的方式去替CPU减负&#xff0c;以保证嵌入式设备性能。例如SD卡存储器和音视频、网络高速通信等其它情…

Java后端技术助力,党员学习平台更稳定

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

Web APIs 2 事件

Web APIs 2 事件 事件监听案例&#xff1a;广告关闭案例&#xff1a;随机问答 事件监听版本事件类型案例&#xff1a;轮播图完整焦点事件键盘事件输入事件案例&#xff1a;评论字数统计 事件对象获取事件对象事件对象常用属性案例&#xff1a;评论回车发布 环境对象this回调函数…

react将选中文本自动滑动到容器可视区域内

// 自动滚动到可视区域内useEffect(() > {const target ref;const wrapper wrapperRef?.current;if (target && wrapperRef) {const rect target.getBoundingClientRect();const wrapperRect wrapper.getBoundingClientRect();const isVisible rect.bottom &l…

跟着pink老师前端入门教程-day21+22

5.4 常见flex布局思路 5.5 背景线性渐变 语法&#xff1a; background: linear-gradient( 起始方向 , 颜色 1, 颜色 2, ...); background: -webkit-linear-gradient(left, red , blue); background: -webkit-linear-gradient(left top, red , blue); 背景渐变必须添加浏览…

2024年【R2移动式压力容器充装】考试题及R2移动式压力容器充装复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 R2移动式压力容器充装考试题是安全生产模拟考试一点通总题库中生成的一套R2移动式压力容器充装复审考试&#xff0c;安全生产模拟考试一点通上R2移动式压力容器充装作业手机同步练习。2024年【R2移动式压力容器充装】…

Markdown:简洁高效的文本标记语言

引言 在当今信息爆炸的时代&#xff0c;我们需要一种简洁、高效的文本标记语言来排版和发布内容。Markdown应运而生&#xff0c;它是一种轻量级的文本标记语言&#xff0c;以其简单易学、易读易写的特点&#xff0c;成为了广大写作者的首选工具。本文将介绍Markdown的语法优缺…

适用于 Windows 和 Mac 的 16 款最佳数据恢复软件

数据恢复软件是找回因硬盘损坏、病毒攻击或意外删除数据等原因而在设备上丢失的数据的最佳方法。在数字世界中&#xff0c;丢失数据是一件非常糟糕的事情&#xff0c;这会让许多人的情况变得更糟。使用最佳数据恢复软件可以减轻您必须努力恢复丢失数据的压力。它将带回您的大部…