滚雪球学Java(72):从零开始掌握Java Queue:深入浅出学习指南

举报
bug菌 发表于 2024/04/14 18:07:43 2024/04/14
【摘要】   咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!!环境说明:Windows 10 +...

在这里插入图片描述

  咦咦咦,各位小可爱,我是你们的好伙伴——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接口中定义了一些基本的方法,下面来一一解析。

  1. add()方法

  add()方法用于在队列的尾部添加一个元素,如果队列已满,则会抛出IllegalStateException异常。

public boolean add(E e);
  1. offer()方法

  offer()方法用于在队列的尾部添加一个元素,如果队列已满,则返回false。

public boolean offer(E e);
  1. remove()方法

  remove()方法用于移除队列头部的元素,如果队列为空,则会抛出NoSuchElementException异常。

public E remove();
  1. poll()方法

  poll()方法用于移除队列头部的元素,如果队列为空,则返回null。

public E poll();
  1. element()方法

  element()方法用于返回队列头部的元素,如果队列为空,则会抛出NoSuchElementException异常。

public E element();

在这里插入图片描述

  1. peek()方法

  peek()方法用于返回队列头部的元素,如果队列为空,则返回null。

public E peek();

  如下是部分源码截图:

在这里插入图片描述

队列的几种实现方式

  1. LinkedList

  LinkedList是一个双向链表,它实现了Deque接口和List接口,因此可以用来实现队列、双端队列和列表等数据结构。在使用LinkedList实现队列时,可以使用add()方法或offer()方法添加元素,remove()方法或poll()方法删除元素,element()方法或peek()方法获取队列头部的元素。

  1. PriorityQueue

  PriorityQueue是一个优先级队列,它可以根据元素的大小自动进行排序。在使用PriorityQueue实现队列时,可以使用add()方法或offer()方法添加元素,remove()方法或poll()方法删除队列头部的元素,element()方法或peek()方法获取队列头部的元素。

  1. ArrayDeque

  ArrayDeque是一个双端队列,它可以用来实现队列、双端队列等数据结构。在使用ArrayDeque实现队列时,可以使用add()方法或offer()方法添加元素,remove()方法或poll()方法删除元素,element()方法或peek()方法获取队列头部的元素。

应用场景案例

消息队列

  消息队列是一种基于异步处理的消息传递机制,通过将消息放入队列中,可以实现跨平台、跨语言的消息传递。在Java中,可以使用Queue接口实现消息队列,通过将消息对象放入队列中,另外一个线程来进行处理。比如在网络应用中,可以将处理请求的线程和接收请求的线程分开,通过消息队列来传递请求信息。

调度任务

  调度任务是一种在指定时间执行指定操作的机制,它可以用来实现周期性任务、延迟任务等。在Java中,可以使用Queue接口实现任务调度机制,通过将任务对象放入队列中,另外一个线程来进行处理。比如在Web应用中,可以将需要定期执行的任务放入队列中,由线程池来执行。

优缺点分析

优点

  1. 队列可以有效地控制任务的执行顺序,确保任务按照一定的顺序进行执行。

  2. 队列可以有效地减轻线程的压力,降低线程之间的竞争,提高程序的并发性能。

  3. 队列可以有效地控制任务的调度时间,根据任务的优先级进行处理,提高程序的效率。

缺点

  1. 队列可能会增加程序的内存消耗,当队列中元素过多时,可能会导致内存溢出等问题。

  2. 队列可能会增加程序的复杂度,需要对任务进行优先级等方面的处理,否则可能会导致任务无法按照预期的顺序进行执行。

类代码方法介绍

LinkedList

  LinkedList是一个双向链表,它实现了Deque接口和List接口,因此可以用来实现队列、双端队列和列表等数据结构。下面是一些常用的方法:

  1. add()方法

add()方法用于在队列的尾部添加一个元素。

public boolean add(E e);
  1. offer()方法

offer()方法用于在队列的尾部添加一个元素。

public boolean offer(E e);
  1. remove()方法

remove()方法用于移除队列头部的元素。

public E remove();
  1. poll()方法

poll()方法用于移除队列头部的元素。

public E poll();
  1. element()方法

element()方法用于返回队列头部的元素。

public E element();
  1. peek()方法

peek()方法用于返回队列头部的元素。

public E peek();

PriorityQueue

  PriorityQueue是一个优先级队列,它可以根据元素的大小自动进行排序。下面是一些常用的方法:

  1. add()方法

add()方法用于将元素添加到队列中。

public boolean add(E e);
  1. offer()方法

offer()方法用于将元素添加到队列中。

public boolean offer(E e);
  1. remove()方法

remove()方法用于移除队列头部的元素。

public E remove();
  1. poll()方法

poll()方法用于移除队列头部的元素。

public E poll();
  1. element()方法

element()方法用于返回队列头部的元素。

  1. peek()方法

peek()方法用于返回队列头部的元素。

public E peek();
  1. 构造方法

  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 对象时指定不同的初始化参数。具体说明如下:

  1. public PriorityQueue():无参构造函数,创建一个默认容量为 11 的优先队列,使用自然顺序进行元素排序。

  2. public PriorityQueue(int initialCapacity):创建一个具有指定初始容量的优先队列,使用自然顺序进行元素排序。

  3. public PriorityQueue(int initialCapacity, Comparator<? super E> comparator):创建一个具有指定初始容量的优先队列,使用指定的比较器进行元素排序。

  4. public PriorityQueue(Collection<? extends E> c):创建一个包含指定集合的元素的优先队列,使用自然顺序进行元素排序。

  5. public PriorityQueue(PriorityQueue<? extends E> c):创建一个具有指定优先队列的元素的优先队列,使用自然顺序进行元素排序。

  6. public PriorityQueue(SortedSet<? extends E> c):创建一个包含指定排序集合的元素的优先队列,使用相同的比较器进行元素排序。

ArrayDeque

  ArrayDeque是一个双端队列,它可以用来实现队列、双端队列等数据结构。下面是一些常用的方法:

  1. add()方法

add()方法用于在队列的尾部添加一个元素。

public boolean add(E e);
  1. offer()方法

offer()方法用于在队列的尾部添加一个元素。

public boolean offer(E e);
  1. remove()方法

remove()方法用于移除队列头部的元素。

public E remove();
  1. poll()方法

poll()方法用于移除队列头部的元素。

public E poll();
  1. element()方法

element()方法用于返回队列头部的元素。

public E element();
  1. peek()方法

peek()方法用于返回队列头部的元素。

public E peek();
  1. 构造方法

  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电子书籍、简历模板等海量资料,你想要的我都有,关键是你不来拿。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。