滚雪球学Java(72):从零开始掌握Java Queue:深入浅出学习指南
咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~
🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!!
环境说明:Windows 10 + IntelliJ IDEA 2021.3.2 + Jdk 1.8
@[toc]
前言
Queue是计算机科学中一个重要的数据结构,它是一种线性数据结构,用于存储按顺序排列的元素集合。在Java中,Queue是一个接口,它可以用来实现FIFO(先进先出)的队列数据结构。队列是一个常用的数据结构,可以用来实现许多重要的算法和程序。
摘要
本文将深入浅出地介绍Java Queue的各种知识点和应用场景,包括Queue的定义、源代码解析、应用场景案例、优缺点分析、类代码方法介绍和测试用例。通过本文的学习,读者将能够全面掌握Java Queue的使用方法和实现原理,从而更好地进行Java开发。
Queue
概述
Queue的定义
在Java中,Queue是一个接口,它继承自Collection接口,因此可以用来存储一组对象。Queue的特点是按照FIFO(先进先出)的原则进行元素的插入和删除。Queue接口中定义了一些基本的方法,如add()、offer()、remove()、poll()、element()和peek()等。
Queue的实现类
在Java中,Queue接口有很多实现类,包括LinkedList、PriorityQueue、ArrayDeque等。这些实现类都继承自Queue接口,并且都实现了Queue接口中定义的基本方法。在选择实现类时,需要根据实际的需求来选择,比如如果需要实现优先级队列,则可以选择PriorityQueue,如果需要实现双端队列,则可以选择ArrayDeque。
Queue的应用场景
Queue常用于异步处理、消息队列、任务队列等场景。比如在Web应用中,如果需要异步处理一些任务,可以将任务放入队列中,由另外一个线程来处理。在消息队列中,消息会按照一定的顺序进行传递,而在任务队列中,任务也会按照一定的顺序进行执行。
源代码解析
Queue接口中的方法
在Java中,Queue接口中定义了一些基本的方法,下面来一一解析。
- add()方法
add()方法用于在队列的尾部添加一个元素,如果队列已满,则会抛出IllegalStateException异常。
public boolean add(E e);
- offer()方法
offer()方法用于在队列的尾部添加一个元素,如果队列已满,则返回false。
public boolean offer(E e);
- remove()方法
remove()方法用于移除队列头部的元素,如果队列为空,则会抛出NoSuchElementException异常。
public E remove();
- poll()方法
poll()方法用于移除队列头部的元素,如果队列为空,则返回null。
public E poll();
- element()方法
element()方法用于返回队列头部的元素,如果队列为空,则会抛出NoSuchElementException异常。
public E element();
- peek()方法
peek()方法用于返回队列头部的元素,如果队列为空,则返回null。
public E peek();
如下是部分源码截图:
队列的几种实现方式
- LinkedList
LinkedList是一个双向链表,它实现了Deque接口和List接口,因此可以用来实现队列、双端队列和列表等数据结构。在使用LinkedList实现队列时,可以使用add()方法或offer()方法添加元素,remove()方法或poll()方法删除元素,element()方法或peek()方法获取队列头部的元素。
- PriorityQueue
PriorityQueue是一个优先级队列,它可以根据元素的大小自动进行排序。在使用PriorityQueue实现队列时,可以使用add()方法或offer()方法添加元素,remove()方法或poll()方法删除队列头部的元素,element()方法或peek()方法获取队列头部的元素。
- ArrayDeque
ArrayDeque是一个双端队列,它可以用来实现队列、双端队列等数据结构。在使用ArrayDeque实现队列时,可以使用add()方法或offer()方法添加元素,remove()方法或poll()方法删除元素,element()方法或peek()方法获取队列头部的元素。
应用场景案例
消息队列
消息队列是一种基于异步处理的消息传递机制,通过将消息放入队列中,可以实现跨平台、跨语言的消息传递。在Java中,可以使用Queue接口实现消息队列,通过将消息对象放入队列中,另外一个线程来进行处理。比如在网络应用中,可以将处理请求的线程和接收请求的线程分开,通过消息队列来传递请求信息。
调度任务
调度任务是一种在指定时间执行指定操作的机制,它可以用来实现周期性任务、延迟任务等。在Java中,可以使用Queue接口实现任务调度机制,通过将任务对象放入队列中,另外一个线程来进行处理。比如在Web应用中,可以将需要定期执行的任务放入队列中,由线程池来执行。
优缺点分析
优点
-
队列可以有效地控制任务的执行顺序,确保任务按照一定的顺序进行执行。
-
队列可以有效地减轻线程的压力,降低线程之间的竞争,提高程序的并发性能。
-
队列可以有效地控制任务的调度时间,根据任务的优先级进行处理,提高程序的效率。
缺点
-
队列可能会增加程序的内存消耗,当队列中元素过多时,可能会导致内存溢出等问题。
-
队列可能会增加程序的复杂度,需要对任务进行优先级等方面的处理,否则可能会导致任务无法按照预期的顺序进行执行。
类代码方法介绍
LinkedList
LinkedList是一个双向链表,它实现了Deque接口和List接口,因此可以用来实现队列、双端队列和列表等数据结构。下面是一些常用的方法:
- add()方法
add()方法用于在队列的尾部添加一个元素。
public boolean add(E e);
- offer()方法
offer()方法用于在队列的尾部添加一个元素。
public boolean offer(E e);
- remove()方法
remove()方法用于移除队列头部的元素。
public E remove();
- poll()方法
poll()方法用于移除队列头部的元素。
public E poll();
- element()方法
element()方法用于返回队列头部的元素。
public E element();
- peek()方法
peek()方法用于返回队列头部的元素。
public E peek();
PriorityQueue
PriorityQueue是一个优先级队列,它可以根据元素的大小自动进行排序。下面是一些常用的方法:
- add()方法
add()方法用于将元素添加到队列中。
public boolean add(E e);
- offer()方法
offer()方法用于将元素添加到队列中。
public boolean offer(E e);
- remove()方法
remove()方法用于移除队列头部的元素。
public E remove();
- poll()方法
poll()方法用于移除队列头部的元素。
public E poll();
- element()方法
element()方法用于返回队列头部的元素。
- peek()方法
peek()方法用于返回队列头部的元素。
public E peek();
- 构造方法
PriorityQueue有多种构造方法,可以根据实际需求进行选择。比如可以使用默认构造方法创建一个初始容量为11的空队列,也可以使用指定Comparator的构造方法创建一个自定义排序规则的队列。
public PriorityQueue();
public PriorityQueue(int initialCapacity);
public PriorityQueue(int initialCapacity, Comparator<? super E> comparator);
public PriorityQueue(Collection<? extends E> c);
public PriorityQueue(PriorityQueue<? extends E> c);
public PriorityQueue(SortedSet<? extends E> c);
如下是针对该构造方法的解析:
上述代码是 PriorityQueue 类的构造函数,提供了多个重载的构造函数,允许用户在创建 PriorityQueue 对象时指定不同的初始化参数。具体说明如下:
-
public PriorityQueue()
:无参构造函数,创建一个默认容量为 11 的优先队列,使用自然顺序进行元素排序。 -
public PriorityQueue(int initialCapacity)
:创建一个具有指定初始容量的优先队列,使用自然顺序进行元素排序。 -
public PriorityQueue(int initialCapacity, Comparator<? super E> comparator)
:创建一个具有指定初始容量的优先队列,使用指定的比较器进行元素排序。 -
public PriorityQueue(Collection<? extends E> c)
:创建一个包含指定集合的元素的优先队列,使用自然顺序进行元素排序。 -
public PriorityQueue(PriorityQueue<? extends E> c)
:创建一个具有指定优先队列的元素的优先队列,使用自然顺序进行元素排序。 -
public PriorityQueue(SortedSet<? extends E> c)
:创建一个包含指定排序集合的元素的优先队列,使用相同的比较器进行元素排序。
ArrayDeque
ArrayDeque是一个双端队列,它可以用来实现队列、双端队列等数据结构。下面是一些常用的方法:
- add()方法
add()方法用于在队列的尾部添加一个元素。
public boolean add(E e);
- offer()方法
offer()方法用于在队列的尾部添加一个元素。
public boolean offer(E e);
- remove()方法
remove()方法用于移除队列头部的元素。
public E remove();
- poll()方法
poll()方法用于移除队列头部的元素。
public E poll();
- element()方法
element()方法用于返回队列头部的元素。
public E element();
- peek()方法
peek()方法用于返回队列头部的元素。
public E peek();
- 构造方法
ArrayDeque也有多种构造方法,可以根据实际需求进行选择。比如可以使用默认构造方法创建一个空队列,也可以使用指定容量的构造方法创建一个具有固定容量的队列。
public ArrayDeque();
public ArrayDeque(int numElements);
public ArrayDeque(Collection<? extends E> c);
测试用例
下面是一个使用Queue来实现消息队列的测试用例:
package com.demo.javase.day72;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
/**
* @Author bug菌
* @Date 2023-11-06 16:25
*/
public class QueueTest {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
queue.add("apple");
queue.add("banana");
queue.add("orange");
queue.add("grape");
System.out.println("Queue : " + queue);
System.out.println("Head : " + queue.remove());
System.out.println("Queue after removal of head : " + queue);
queue.add("pear");
System.out.println("Queue after addition of an element : " + queue);
System.out.println("Head : " + queue.peek());
System.out.println("Size of queue : " + queue.size());
}
}
测试结果
根据如上测试用例,本地测试结果如下,仅供参考,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。
上面的代码定义了一个MessageQueue类,它使用Queue接口来实现消息队列。在主函数中,先向消息队列中添加了一条消息,然后不断从队列中取出消息进行处理。
输出结果如下:
Queue : [apple, banana, orange, grape]
Head : apple
Queue after removal of head : [banana, orange, grape]
Queue after addition of an element : [banana, orange, grape, pear]
Head : banana
Size of queue : 4
实际执行截图如下:
测试代码分析
根据如上测试用例,在此我给大家进行深入详细的解读一下测试代码,以便于更多的同学能够理解并加深印象。
该代码主要演示了Java中的队列(Queue)数据结构的使用,通过LinkedList实现了一个队列。具体操作包括向队列中添加元素、获取队列头部元素并移除、获取队列头部元素但不移除、向队列尾部添加元素,以及获取队列大小。运行该代码会输出相应的结果,方便我们理解队列的基本操作。该代码主要演示了Java中的队列(Queue)数据结构的使用,通过LinkedList实现了一个队列。具体操作包括向队列中添加元素、获取队列头部元素并移除、获取队列头部元素但不移除、向队列尾部添加元素,以及获取队列大小。运行该代码会输出相应的结果,方便我们理解队列的基本操作。
小结
本文主要介绍了Java中常用的三种队列:LinkedList、PriorityQueue和ArrayDeque以及它们的方法和构造方式。LinkedList是一个双向链表,可用于实现队列、双端队列和列表等数据结构;PriorityQueue是一个优先级队列,按照元素大小自动排序,常用于任务调度;ArrayDeque是一个双端队列,可用于实现队列、双端队列等数据结构。在实际开发中,我们可以根据不同的需求选择不同的数据结构。最后,本文还给出了一个使用Queue接口实现消息队列的测试用例。
总结
本文主要介绍了 Java Queue 的概念、定义、实现类、应用场景、优缺点分析、类代码方法介绍和测试用例,并且对 Queue 接口中的基本方法进行了源代码解析。其中,Queue 是一个用于按照先进先出原则进行元素插入和删除的数据结构,Java 中有很多 Queue 的实现类,包括 LinkedList、PriorityQueue、ArrayDeque 等。它们都继承自 Queue 接口,并且都实现了 Queue 接口中定义的基本方法。
在应用场景方面,Queue 常用于异步处理、消息队列、任务队列等场景。在消息队列中,可以通过将消息对象放入队列中,另外一个线程来进行处理。在任务队列中,可以通过将需要定期执行的任务放入队列中,由线程池来执行。
最后,本文还给出了 Queue 实现类的常用方法的介绍,并且通过一个使用 Queue 来实现消息队列的测试用例进行了说明。
… …
好啦,这期的内容就基本接近尾声啦,若你想学习更多,你可以看看专栏的导读篇《「滚雪球学Java」教程导航帖》,本专栏致力打造最硬核 Java 零基础系列学习内容,🚀打造全网精品硬核专栏,带你直线超车;欢迎大家订阅持续学习。功不唐捐,久久为功!
「赠人玫瑰,手留余香」,咱们下期拜拜~~
附录源码
如上涉及所有源码均已上传同步在「Gitee」,提供给同学们一对一参考学习,辅助你更迅速的掌握。
☀️建议/推荐你
无论你是计算机专业的学生,还是对编程感兴趣的跨专业小白,都建议直接入手「滚雪球学Java」专栏;该专栏不仅免费,bug菌还郑重承诺,只要你学习此专栏,均能入门并理解Java SE,以全网最快速掌握Java语言,每章节源码均同步「Gitee」,你真值得拥有;学习就像滚雪球一样,越滚越大,带你指数级提升。
码字不易,如果这篇文章对你有所帮助,帮忙给bugj菌来个一键三连(关注、点赞、收藏) ,您的支持就是我坚持写作分享知识点传播技术的最大动力。
同时也推荐大家关注我的硬核公众号:「猿圈奇妙屋」 ;以第一手学习bug菌的首发干货,不仅能学习更多技术硬货,还可白嫖最新BAT大厂面试真题、4000G Pdf技术书籍、万份简历/PPT模板、技术文章Markdown文档等海量资料,你想要的我都有!
📣关于我
我是bug菌,CSDN | 掘金 | InfoQ | 51CTO | 华为云 | 阿里云 | 腾讯云 等社区博客专家,C站博客之星Top30,华为云2023年度十佳博主,掘金多年度人气作者Top40,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者;全网粉丝合计 20w+;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试真题、4000G PDF电子书籍、简历模板等海量资料,你想要的我都有,关键是你不来拿。
- 点赞
- 收藏
- 关注作者
评论(0)