Java队列详细解释

队列

一、什么是队列(Queue)

    ```java
    队列是一种线性数据结构,它的特点是先进先出。在队列中,元素的添加(入队)操作在队尾进行,而元素的移除(出队)操作则在队头进行。因此,队列可以被简单地描述为一个“先进先出”的容器。在Java中,队列接口继承自Collection接口,并提供了丰富的方法来操作队列中的元素
    ```

Java 的队列主要通过 java.util.Queue 接口及其子接口和实现类来定义和使用。根据不同的特性和用途,队列可以分为以下几类:

  1. 普通队列(FIFO 队列)

  2. 双端队列(Deque)

  3. 优先级队列(Priority Queue)

  4. 阻塞队列(Blocking Queue)

    提供阻塞操作,当队列为空时,获取元素的线程会等待;当队列已满时,添加元素的线程会等待。
    常用于生产者-消费者模式。
    
  5. 同步队列(Synchronous Queue)

SynchronousQueue 本质上是一个没有容量的队列,每个插入操作必须等待一个对应的移除操作,反之亦然。它常用于线程之间的直接交换数据。
不存储元素:
每个 put 必须等待一个 take,每个 take 必须等待一个 put。

如下:普通队列

在这里插入图片描述

在这里插入图片描述

在 Java 中,Queuejava.util 包下的一个接口,继承自 Collection 接口。Queue 定义了基本的队列操作方法,如添加、删除和查看元素。Queue 接口不能被直接实例化,但 Java 提供了多个实现类,例如 LinkedListPriorityQueueArrayDeque 等。

在这里插入图片描述

从上面类的继承关系图可以看到Queue是一个接口,它的内部主要定义了以下几个方法:

二、常用方法

在这里插入图片描述

1.offer( )和add( )方法的区别

Queue<String> queue = new LinkedList<>();
queue.add("A");
queue.offer("B");
// 队列中的元素:[A, B]

对于offer():往队列添加元素。在不违反容量限制的情况下立即执行,将指定的元素插入到队列中。如果队列已满直接返回false,队列未满则直接插入并返回true;
对于add():如果队列已满,抛出异常IllegalStateException。

2.poll( )和remove( )方法的区别

Queue<String> queue = new LinkedList<>();
queue.add("A");
queue.add("B");
String headElement = queue.remove();
// headElement 的值为 "A",队列中的元素:[B]

对于poll():检索并删除此队列的头,如果此队列为空,则返回 null ;
对于remove():检索并删除此队列的头。 此方法与poll不同之处在于,如果此队列为空,它将抛出异常。

3.peek()和element( )方法的区别

Queue<String> queue = new LinkedList<>();
queue.add("A");
queue.add("B");
String headElement = queue.element();
// headElement 的值为 "A",队列中的元素:[A, B]

对于peek():检索但不删除此队列的头部,如果此队列为空,则返回 null ;
对于element():检索但不删除这个队列的头。 此方法与peek的不同之处在于,如果此队列为空,它将抛出异常。

三、Java 中队列的实现类

Java 提供了多个 Queue 接口的实现,每种实现类都有不同的特点和应用场景。

1. LinkedList

LinkedList 类实现了 Queue 接口,并且可以作为队列使用。它是一个双向链表,支持队列的基本操作。LinkedList 适合频繁的插入和删除操作。

  • 特点
    • 动态大小,插入和删除操作性能较好。
  • 代码示例
import java.util.LinkedList;
import java.util.Queue;

public class LinkedListQueueExample {
    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<>();//多态
        // 添加元素
        queue.add("A");
        queue.add("B");
        queue.add("C");
        // 查看队列头部元素
        
        System.out.println("Queue head: " + queue.peek());
        // 移除元素
        
        System.out.println("Removed: " + queue.remove());

        // 查看队列内容
        System.out.println("Queue content: " + queue);
    }
}

输出

Queue head: A
Removed: A
Queue content: [B, C]

2. PriorityQueue 优先级队列

PriorityQueue 是一个基于堆的优先队列实现,它不会遵循普通的先进先出(FIFO)规则,而是根据元素的 优先级 来确定出队顺序。默认情况下,它是最小堆,即每次移除的是队列中的最小元素。

  • 特点

    • 不保证元素的顺序,插入元素根据优先级调整。
    • 插入元素时间复杂度为 O(log n),移除元素时间复杂度为 O(log n)
  • 代码示例

import java.util.PriorityQueue;
import java.util.Queue;

public class PriorityQueueExample {
    public static void main(String[] args) {
        Queue<Integer> queue = new PriorityQueue<>();

        // 添加元素
        queue.add(5);
        queue.add(2);
        queue.add(8);
        queue.add(1);

        // 移除并查看元素
        while (!queue.isEmpty()) {
            System.out.println("Removed: " + queue.poll());
        }
    }
}

输出

Removed: 1
Removed: 2
Removed: 5
Removed: 8

优先级案例

public class Task implements Comparable<Task> {
    private String name;
    private int priority;

    public Task(String name, int priority) {
        this.name = name;
        this.priority = priority;
    }

    public String getName() {
        return name;
    }

    public int getPriority() {
        return priority;
    }

    @Override
    public int compareTo(Task other) {
        return other.getPriority() - this.getPriority();
    }
}

import java.util.PriorityQueue;

public class Test {
    public static void main(String[] args) {
        PriorityQueue<Task> queue = new PriorityQueue<>();
        queue.add(new Task("Task 1", 5));
        queue.add(new Task("Task 2", 3));
        queue.add(new Task("Task 3", 10));
        queue.add(new Task("Task 4", 15));
        queue.add(new Task("Task 5", 1));
        while (!queue.isEmpty()) {
            Task task = queue.poll();
            String name = task.getName();
            System.out.println("Executing task: " + name);
        }
    }

}
添加元素时调用 compareTo 的原因
PriorityQueue 内部使用了 堆排序,通常是二叉堆,这是一种可以快速找到最大值或最小值的数据结构。在向堆中添加元素时,堆需要重新排序,以保持其“堆性质”。为了决定新元素应该放在什么位置,它必须和其他元素进行比较,而这个比较就是通过 compareTo 方法来完成的。
    
hashCode()equals() 通常一起重写,以确保两个相等的对象有相同的哈希码。如果对象被放入某些数据结构,如 HashSet 或作为键在 HashMap 中时,Java 会先调用 hashCode() 来确定它们的位置,然后通过 equals() 来判断对象的相等性。尽管 PriorityQueue 本身不使用 hashCode(),但如果你在这些数据结构中存储 Task 对象,hashCode() 将会被调用。

3. ArrayDeque

ArrayDequeDeque 接口的实现类,可以用作双端队列或栈。作为队列时,它比 LinkedList 更加高效。ArrayDeque 使用动态数组来存储元素,能够支持双端的插入和删除操作。

特点:

  • 无大小限制的双端队列,能够从两端插入和删除元素。
1. 作为栈使用(后进先出 - LIFO)

使用 ArrayDeque 可以模拟栈的操作,常见的方法包括:

  • push(E e):将元素压入栈顶。

  • pop():弹出栈顶元素。

  • peek():查看栈顶元素但不移除。

    在这里插入图片描述

import java.util.ArrayDeque;

public class StackExample {
    public static void main(String[] args) {
        ArrayDeque<String> stack = new ArrayDeque<>();

        // 模拟栈操作
        stack.push("Element 1");
        stack.push("Element 2");
        stack.push("Element 3");

        // 查看栈顶元素
        System.out.println("Top of the stack: " + stack.peek());  
        // 输出 "Element 3"
        // 弹出栈顶元素
        System.out.println("Popped: " + stack.pop()); 
        // 输出 "Element 3"
        System.out.println("Popped: " + stack.pop());  
        // 输出 "Element 2"

        // 再次查看栈顶
        System.out.println("Top of the stack: " + stack.peek()); 
        // 输出 "Element 1"
    }
}

2.作为队列使用(先进先出 - FIFO)

offer(E e):将元素添加到队列尾部。

poll():移除并返回队列头部的元素。

peek():查看队列头部的元素但不移除。

代码示例:

import java.util.ArrayDeque;

public class QueueExample {
    public static void main(String[] args) {
        ArrayDeque<String> queue = new ArrayDeque<>();

        // 模拟队列操作
        queue.offer("Element 1");
        queue.offer("Element 2");
        queue.offer("Element 3");

        // 查看队列头部元素
        System.out.println("Front of the queue: " + queue.peek());  
        // 输出 "Element 1"

        // 移除队列头部元素
        System.out.println("Removed: " + queue.poll());  
        // 输出 "Element 1"
        System.out.println("Removed: " + queue.poll()); 
        // 输出 "Element 2"

        // 再次查看队列头部
        System.out.println("Front of the queue: " + queue.peek()); 
        // 输出 "Element 3"
    }
}

3.双端队列操作(简称Deque)

ArrayDeque 允许你在队列的两端进行操作,可以在头部或尾部添加和删除元素。

addFirst(E e) / addLast(E e):在头部或尾部添加元素。

removeFirst() / removeLast():移除并返回头部或尾部的元素。

import java.util.ArrayDeque;

public class DequeExample {
    public static void main(String[] args) {
        ArrayDeque<String> deque = new ArrayDeque<>();

        // 在头部和尾部添加元素
        deque.addFirst("Element 1");
        deque.addLast("Element 2");
        deque.addFirst("Element 0");

        // 输出双端队列的内容
        System.out.println(deque);  
        // 输出 "[Element 0, Element 1, Element 2]"

        // 移除头部和尾部元素
        System.out.println("Removed from head: " + deque.removeFirst());  			// 输出 "Element 0"
        System.out.println("Removed from tail: " + deque.removeLast());  			// 输出 "Element 2"

        // 最终的队列状态
        System.out.println(deque);  // 输出 "[Element 1]"
    }
}

栈操作:push()pop()peek()。

队列操作:offer()poll()peek()。

双端队列操作:addFirst()addLast()removeFirst()removeLast()

四、阻塞队列(Blocking Queue)

常见实现类:
ArrayBlockingQueue
LinkedBlockingQueue
PriorityBlockingQueue
SynchronousQueue
DelayQueue
    
    
常用方法
    put(E e)	将元素 e 插入队列,若队列满则阻塞等待。
    take()	移除并返回队列头部元素,若队列为空则阻塞等待。	阻塞方法
    offer(E e)	尝试将元素 e 插入队列,若队列满则返回 false
1.ArrayBlockingQueue

一个有界的阻塞队列,基于数组实现,按照 FIFO 顺序排列元素。

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class ArrayBlockingQueueExample {
    public static void main(String[] args) throws InterruptedException {
     BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
 3表示 阻塞队列的容量上限。也就是说,这个 LinkedBlockingQueue 最多只能存储 3 个元素。
        // 添加元素,使用 put 方法会阻塞直到有空间
        blockingQueue.put("Task 1");
        blockingQueue.put("Task 2");
        blockingQueue.put("Task 3");
        // blockingQueue.put("Task 4");  // 会阻塞,直到有空间

        // 查看队列内容
        System.out.println("Queue: " + blockingQueue);

        // 移除元素,使用 take 方法会阻塞直到有元素
        System.out.println("Taken: " + blockingQueue.take());  
        // 移除 "Task 1"
        System.out.println("Taken: " + blockingQueue.take()); 
        // 移除 "Task 2"

        // 添加新的元素
        blockingQueue.put("Task 4");

        // 最终队列内容
        System.out.println("Queue: " + blockingQueue);
    }
}

2.LinkedBlockingQueue

一个基于链表的阻塞队列,可以选择有界或无界。

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class LinkedBlockingQueueExample {
    public static void main(String[] args) throws InterruptedException {
     BlockingQueue<String> blockingQueue = new LinkedBlockingQueue<>(5);

        // 添加元素
        blockingQueue.offer("Task A");
        blockingQueue.offer("Task B");
        blockingQueue.offer("Task C");

        // 查看队列内容
        System.out.println("Queue: " + blockingQueue);

        // 移除元素
        System.out.println("Removed: " + blockingQueue.poll()); 
        // 移除 "Task A"

        // 添加新元素
        blockingQueue.offer("Task D");

        // 最终队列内容
        System.out.println("Queue: " + blockingQueue);
    }
}

3.PriorityBlockingQueue

一个支持优先级排序的无界阻塞队列。

import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class PriorityBlockingQueueExample {
    public static void main(String[] args) throws InterruptedException {
BlockingQueue<Integer> priorityBlockingQueue =newPriorityBlockingQueue<>();

        // 添加元素
        priorityBlockingQueue.put(20);
        priorityBlockingQueue.put(10);
        priorityBlockingQueue.put(30);
        priorityBlockingQueue.put(5);

        // 按优先级顺序移除元素
        while (!priorityBlockingQueue.isEmpty()) {
            System.out.println(priorityBlockingQueue.take());
            // 输出顺序: 5, 10, 20, 30
        }
    }
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

最近大模型最火的就业方向有哪些?

在2023和2024年&#xff0c;大语言模型的发展迎来了绝对风口&#xff0c;吸引了大量创业者和投资者。然而&#xff0c;经过一年的发展&#xff0c;许多公司已经销声匿迹。那么&#xff0c;未来大模型方向上还有哪些可以继续发展的方向呢? 基座大模型预训练 现状 - 展现出“胜…

TikTok Live与跨境电商的深度融合:直播带货引领品牌出海

在TikTok Live的应用中&#xff0c;品牌能够利用这一互动性极强的功能开辟新的销售渠道&#xff0c;推动全球业务的增长。本文Nox聚星将和大家探讨TikTok Live如何与跨境电商相结合&#xff0c;分析其应用场景。 一、TikTok Live与跨境电商的结合优势 庞大的用户基础&#xff…

使用 OpenCV 和 NumPy 进行图像处理:HSV 范围筛选实现PS抠图效果

使用 OpenCV 和 NumPy 进行图像处理&#xff1a;HSV 范围筛选实现PS抠图效果 在计算机视觉和图像处理领域&#xff0c;OpenCV 是一个非常强大的库&#xff0c;能够帮助我们执行各种图像操作。在这篇博客中&#xff0c;我们将通过一个简单的示例演示如何使用 OpenCV 和 NumPy 来…

machine learning - 2

泛化误差 也可以认为是预测时的误差。 训练误差 并不是越小越好&#xff0c;太小会过拟合。 获得测试集合的方法&#xff1a; 1&#xff09;&#xff1a; 2&#xff09;&#xff1a;例如&#xff1a;k-折交叉验证法&#xff0c; 就的每k个数据取一个座位测试集 3&#xff0…

1.39TB高清卫星影像更新(WGS84坐标投影)

最近对WGS84版的高清卫星影像数据进行了一次更新&#xff0c;并基于更新区域生成了相应的接图表。 1.39TB高清卫星影像更新 本次数据更新了1576个离线包&#xff0c;共1.39TB大小&#xff0c;并全部生成了更新接图表。 更新接图表范围 更新接图表由每一个离线包文件的范围构…

rancher upgrade 【rancher 升级】

文章目录 1. 背景2. 下载3. 安装4. 检查5. 测试5.1 创建项目5.2 创建应用5.3 删除集群5.4 注册集群 1. 背景 rancher v2.8.2 升级 v2.9.1 2. 下载 下载charts helm repo add rancher-latest https://releases.rancher.com/server-charts/latest helm repo update helm fetc…

支付宝开放平台-开发者社区——AI 日报「9 月 6 日」

1 3天把Llamaill成Mamba&#xff0c; 性能不降&#xff0c;推理更快&#xff01; 新智元 丨阅读原文 康奈尔和普林斯顿的研究人员成功将大型Transformer模型Llama提炼成Mamba模型&#xff0c;并设计了新的推测解码算法&#xff0c;显著提高了模型的推理速度。研究团队采用了渐…

Android OpenGLES开发:EGL环境搭建

努力&#xff0c;不是为了要感动谁&#xff0c;也不是要做给哪个人看&#xff0c;而是要让自己随时有能力跳出自己厌恶的圈子&#xff0c;并拥有选择的权利&#xff0c;用自己喜欢的方式过一生&#xff01; EGL是什么&#xff1f; 谈到openGL开发我们就不得不说EGL&#xff0c…

零基础5分钟上手亚马逊云科技-开发云原生网站应用

简介&#xff1a; 欢迎来到小李哥全新亚马逊云科技AWS云计算知识学习系列&#xff0c;适用于任何无云计算或者亚马逊云科技技术背景的开发者&#xff0c;通过这篇文章大家零基础5分钟就能完全学会亚马逊云科技一个经典的服务开发架构方案。 我会每天介绍一个基于亚马逊云科技…

调度台在现代社会中发挥哪些重要作用

在当今这个高度信息化、快节奏的社会中&#xff0c;调度台作为各行各业运行管理的中枢神经&#xff0c;正发挥着日益重要的作用。它不仅是一个物理上的工作平台&#xff0c;更是信息汇聚、指令发出、资源调配的核心节点&#xff0c;对于保障社会正常运转、提升服务效率、应对突…

tkcalendar中的DateEntry

tkcalendar中的DateEntry可进行时间选择&#xff0c;在Python环境中可以直接使用&#xff0c;但是打包过程中&#xff0c;pyinstaller -F -w -i nss.ico xxx.py,DateEntry是用不了&#xff0c;不显示&#xff0c;打包使用pyinstaller -F -w -i nss.ico --hidden-import babel.n…

spring boot(学习笔记第十九课)

spring boot(学习笔记第十九课) Spring boot的batch框架&#xff0c;以及Swagger3(OpenAPI)整合 学习内容&#xff1a; Spring boot的batch框架Spring boot的Swagger3&#xff08;OpenAPI&#xff09;整合 1. Spring boot batch框架 Spring Batch是什么 Spring Batch 是一个…

dp练习【4】

最长数对链 646. 最长数对链 给你一个由 n 个数对组成的数对数组 pairs &#xff0c;其中 pairs[i] [lefti, righti] 且 lefti < righti 。 现在&#xff0c;我们定义一种 跟随 关系&#xff0c;当且仅当 b < c 时&#xff0c;数对 p2 [c, d] 才可以跟在 p1 [a, b…

Ubuntu环境的MySql下载安装

下载压缩包 此文章下载的mysql版本位5.7.29 sudo wget https://downloads.mysql.com/archives/get/p/23/file/mysql-server_5.7.29-1ubuntu18.04_amd64.deb-bundle.tar解压缩 sudo tar -xvf mysql-server_5.7.29-1ubuntu18.04_amd64.deb-bundle.tar命令解释 -x&#xff1a;…

鸿蒙MPChart图表自定义(四)短刻度线

对于图表中的x轴效果&#xff0c;我们有时想要实现如图所示的特定刻度线。若需绘制x轴的短刻度线&#xff0c;我们可以利用现有资源&#xff0c;将原本的网格线稍作修改&#xff0c;只需绘制一条简洁的短线即可达到目的。 具体的方法就是写一个类MyXAxisRender继承自XAxisRend…

【补-网络安全】日常运维(二)终端端口占用排查

文章目录 一、利用ipconfig、netstat 命令行统计二 、策略封禁IP 引言:检查频繁,第一步我们梳理完资产,第二步应该对资产终端进行一个排查,诊断把脉,了解清楚系统的端口占用及开放情况 一、利用ipconfig、netstat 命令行统计 1.先用ipconfig定位该终端的IP地址 2.明确IP地址后…

汇编语言在虚拟机中输出“Hello World!”

1.软件 Nasmide64.exe(李忠老师编写) Fixvhdw64.exe(李忠老师编写) VirtualBox虚拟机(免费 开源) 2.过程 01.Fixvhdw64.exe输入以下代码: mov ax,0xb800 mov ds,ax mov byte [0x00],H mov byte [0x02],e mov byte [0x04],l mov byte [0x06],l mov byte [0x08],o mov byte…

x-cmd pkg | tig - 基于 nucurses 的 git 文本模式界面

目录 简介首次用户快速实验指南功能特点类似工具与竞品进一步探索 简介 tig 由 Jonas Fonseca 于 2006 年使用 C 语言创建的 git 交互式文本命令行工具。旨在开启交互模式快速浏览 git 存储库的信息以及 git 命令的运行。 首次用户快速实验指南 本文的 demo 展现了如何通过 …

2024年高教杯国赛(D题)数学建模竞赛解题思路|完整代码论文集合

我是Tina表姐&#xff0c;毕业于中国人民大学&#xff0c;对数学建模的热爱让我在这一领域深耕多年。我的建模思路已经帮助了百余位学习者和参赛者在数学建模的道路上取得了显著的进步和成就。现在&#xff0c;我将这份宝贵的经验和知识凝练成一份全面的解题思路与代码论文集合…

2024国赛数学建模ABC题思路模型

完整的思路模型请查看文末名片 完整的思路模型请查看文末名片 完整的思路模型请查看文末名片