Java中队列

news2024/11/15 19:37:30

队列是一种常见的数据结构,它按照先进先出(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.coloradmin.cn/o/1595603.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kafka 简单介绍

目录 一 消息队列&#xff08;MQ&#xff09; 1&#xff0c;为什么需要消息队列&#xff08;MQ 2&#xff0c;常见的 MQ 中间件 3&#xff0c;MQ 传统应用场景之异步处理 4&#xff0c;使用消息队列的好处 5&#xff0c;消息队列的两种模式 5.1点对点模式&#xf…

软件测试基础知识点汇总

1、衡量一个优秀软件的维度 质量模型&#xff1a;功能性、性能、兼容性、易用性、可靠性、安全、可维护性、可移植性。 2、软件测试流程 需求评审、计划编写、用例设计、用例执行、缺陷管理、测试报告 3、用例设计编写格式 用例编号、用例标题、项目/模块、优先级、前置条…

问题、目标与实现

这是2022年初写的。 目录 一、要点 二、难点 ​编辑 三、痛点 四、近点 五、远点 ​编辑 六、细点 6.1 裸机构建 6.1.1 资源、人员、工时 6.1.2 说明 6.2 文档整理 6.2.1 资源、人员、工时 6.2.3 说明 6.3 项目助理 6.4 独立测试环境、演示环境和压力测试 6.5 SC…

如何选好一款护眼大路灯?选落地灯必备的6个技巧

近年来学生近视的现象越来越严重了&#xff0c;而且近视的年龄也越来越小了&#xff0c;不少还没开始上小学的孩子&#xff0c;就已经戴上了厚厚的近视眼镜。而那些高年级的学生更是近视的重灾区&#xff0c;不仅每天需要高强度的学习和长时间用眼&#xff0c;甚至晚上都还需要…

运动耳机哪个牌子好?五大高分机型大力推荐

对于热爱运动的朋友们来说&#xff0c;一款合适的运动蓝牙耳机不仅能提升运动时的愉悦感&#xff0c;还能在一定程度上保证运动的安全性。但是&#xff0c;市面上的运动蓝牙耳机种类繁多&#xff0c;如何挑选一款适合自己的产品呢&#xff1f;本文将从多个角度为你分析运动蓝牙…

如何发布自己的Python库?

Python包发布 1、背景概述2、操作指南 1、背景概述 为什么我们要发布自己的Python库&#xff1f;如果你想让你的Python代码&#xff0c;通过pip install xxx的方式供所有人下载&#xff0c;那就需要将代码上传到PyPi上&#xff0c;这样才能让所有人使用 那么&#xff0c;如何发…

模拟Android系统Zygote启动流程

版权声明&#xff1a;本文为梦想全栈程序猿原创文章&#xff0c;转载请附上原文出处链接和本声明 前言&#xff1a; 转眼时间过去了10年了&#xff0c;回顾整个10年的工作历程&#xff0c;做了3年的手机&#xff0c;4年左右的Android指纹相关的工作&#xff0c;3年左右的跟传感…

Java快速入门系列-9(Spring框架与Spring Boot —— 深度探索及实践指南)

第九章:Spring框架与Spring Boot —— 深度探索及实践指南 9.1 Spring框架概述9.2 Spring IoC容器9.3 Spring AOP9.4 Spring MVC9.5 Spring Data JPA/Hibernate9.6 Spring Boot快速入门与核心特性9.7 Spring Boot的自动配置与启动流程详解9.8 创建RESTful服务与数据库交互实践…

数字化仪:为何成为示波器的理想替代品?——PCIe8910M

在现代科技领域&#xff0c;数字化仪逐渐成为示波器的理想替代品。数字化仪具备诸多特点&#xff0c;使其在多个应用场景下表现出色&#xff0c;逐渐取代传统的示波器。本期文章将探讨数字化仪相对于示波器的优势&#xff0c;以及其哪些特点使其成为示波器的理想替代品。 简介…

AI时代的计算核心,你了解多少?

CPU是中央处理单元&#xff0c;那么GPU是什么呢&#xff1f; CPU的作用是计算机的运算核心和控制核心&#xff0c;GPU作用是什么呢&#xff1f; CPU的大小叫着内存大小&#xff0c;那GPU的大小叫什么呢&#xff1f; 下面我们来聊聊GPU 说起GPU&#xff0c;先来看看我们更为…

将Ubuntu18.04默认的python3.6升级到python3.8

1、查看现有的 python3 版本 python3 --version 2、安装 python3.8 sudo apt install python3.8 3、将 python3.6 和 3.8 添加到 update-alternatives sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 1 sudo update-alternatives --insta…

虚拟资源素材会员交易平台网站源码 带完整源码及教程

今天给大家分享一个虚拟资源素材下载站源码系统&#xff0c;这是一款大家非常需要的虚拟资源下载站源码系统&#xff0c;拥有强大的会员功能&#xff0c;可以单独售卖资源&#xff0c;或者开通会员进行打折购买&#xff0c;或者超级VIP免费下载等等&#xff0c;支持按照时间开通…

为什么看到这么多人不推荐C++?

前几天逛知乎的时候&#xff0c;看到一个问题&#xff1a; 看到这个问题我倒是想吐槽几句了。 C一直没找到自己的定位&#xff01; C语言&#xff1a;我是搞系统编程开发的&#xff0c;操作系统、数据库、编译器、网络协议栈全是我写的。 PHP&#xff1a;我是搞后端业务开发…

不花一分钱,四大方法教你免费申请SSL证书

在数字化时代&#xff0c;数据安全与隐私保护的重要性日益凸显。为了确保在线信息传输的机密性和完整性&#xff0c;数字证书&#xff0c;尤其是SSL/TLS证书扮演着至关重要的角色。为个人及企业用户提供了经济、高效的加密解决方案。随着市场对SSL证书的逐渐重视&#xff0c;免…

Vue3 笔记

1. Vue3简介 2020年9月18日&#xff0c;Vue.js发布版3.0版本&#xff0c;代号&#xff1a;One Piece&#xff08;n 经历了&#xff1a;4800次提交、40个RFC、600次PR、300贡献者 官方发版地址&#xff1a;Release v3.0.0 One Piece vuejs/core 截止2023年10月&#xff0c;最…

idea 中运行spring boot 项目报 Command line is too long的解决办法。

Command line is too long 在这里选择edit configures 选择shrten command line , 选择 jar manifest 运行即可。

【Docker】docker原理及使用-1

Docker目录 1️⃣概念2️⃣使用容器的好处2️⃣docker和普通软件启动方式的区别2️⃣docker和传统虚拟机的区别 1️⃣下载安装2️⃣安装步骤 1️⃣必须要掌握的核心概念1️⃣命令2️⃣例子2️⃣练习题目2️⃣进入一下python环境(简洁) 1️⃣解释一下 redis1️⃣docker底层隔离机…

Spring框架中的单例bean是线程安全的吗?

无状态bean&#xff1a; 无状态的Bean的行为不受其内部状态的影响&#xff0c;每次调用都是基于传入的参数进行计算&#xff0c;而不依赖于任何之前的状态。 (例如上面例子&#xff1a;userService是不能修改的&#xff0c;是无状态的bean) 因此&#xff1a; Spring框架中的…

【位运算】Leetcode 丢失的数字

题目解析 268. 丢失的数字 本题的意思就是数组的长度为n&#xff0c;在[0,n]区间中寻找缺失的一个数字 算法讲解 直观思路&#xff1a;排序 Hash&#xff0c;顺序查找缺失的数字 优化&#xff1a;使用异或&#xff0c;首先将[0,n]之间所有数字异或在一起&#xff0c;然后将…

django 模板js文件为什么最后引入

<!-- 引入Bootstrap JS --> <script src"https://cdn.jsdelivr.net/npm/bootstrap5.3.0/dist/js/bootstrap.bundle.min.js"></script> 为什么最后引入例子 <!-- templates/inspection_records.html --><!DOCTYPE html> <html lang…