Java中队列

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

在这里插入图片描述
不足之处,望海涵!!!

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

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

相关文章

七大设计原则

在软件开发的领域中&#xff0c;随着技术的不断进步和市场需求的不断变化&#xff0c;软件系统的设计和维护变得越来越重要。为了确保软件系统能够长期有效地运行&#xff0c;并且能够在未来的发展中适应新的需求和技术变化&#xff0c;提高软件系统的可维护性和可复用性成为了…

机器学习—特征预处理和降维(四)

什么是特征预处理&#xff1f; 通过一些转换函数将特征数据转换成更加适合算法模型的特征数据过程 1包含内容 数值型数据的无量纲化&#xff1a; 归一化标准化 2特征预处理API sklearn. preprocessing为什么要进行归一化 or 标准化&#xff1f; 特征的单位或者大小相差较大…

vue源码解析——diff算法/双端比对/patchFlag/最长递增子序列

虚拟dom——virtual dom&#xff0c;提供一种简单js对象去代替复杂的 dom 对象&#xff0c;从而优化 dom 操作。virtual dom 是“解决过多的操作 dom 影响性能”的一种解决方案。virtual dom 很多时候都不是最优的操作&#xff0c;但它具有普适性&#xff0c;在效率、可维护性之…

BackTrader 中文文档(十一)

原文&#xff1a;www.backtrader.com/ 基准测试 原文&#xff1a;www.backtrader.com/docu/observer-benchmark/benchmarking/ 票号 #89 是关于添加对资产的基准测试的。理智的做法是&#xff0c;即使有一种策略&#xff0c;即使是正的&#xff0c;也低于简单跟踪资产将提供的内…

第⑭讲:Ceph集群管理:守护进程管理、日志管理和端口号配置

文章目录 1.Ceph各组件守护进程的管理方式2.守护进程管理操作2.1.Ceph所有组件的守护进程列表2.2.重启当前主机中所有的Ceph组件2.3.重启主机中所有的Monitor组件2.4.重启指定主机的Monitor组件2.5.重启指定的OSD组件 3.Ceph的日志管理4.Ceph集群各组件的守护进程5.Ceph集群各组…

All in One:Prometheus 多实例数据统一管理最佳实践

作者&#xff1a;淡唯&#xff08;啃唯&#xff09;、阳其凯&#xff08;逸陵&#xff09; 引言 Prometheus 作为目前最主流的可观测开源项目之一&#xff0c;已经成为云原生监控的事实标准&#xff0c;被众多企业广泛应用。在使用 Prometheus 的时候&#xff0c;我们经常会遇…

自然语言处理: 第二十六章大模型基底之Mistral 8x7B

文章地址: 2401.04088.pdf (arxiv.org) 项目地址: mistralai/mistral-src: Reference implementation of Mistral AI 7B v0.1 model 前言: 本文意在一文深度剖析Mistral 8X7B的关键改进点。 Mistral AI是一个由DeepMind和Meta的三位前员工在巴黎共同创立的AI公司。其在23年…

tsconfig.json文件常用配置

最近在学ts&#xff0c;因为tsconfig的配置实在太多啦&#xff0c;所以写此文章用作记录&#xff0c;也作分享 作用&#xff1f; tsconfig.jsono是ts编译器的配置文件&#xff0c;ts编译器可以根据它的信息来对代码进行编译 初始化一个tsconfig文件 tsc -init配置参数解释 …

股票开户佣金最低多少?万一!A股开户多少钱合适?

开户佣金 通常情况下&#xff0c;股票开户佣金只要在达成交易的前提才收手续的费用&#xff0c;即买入和卖出的时候。目前&#xff0c;国规定收取最高佣金的比例为千分之三。 也就是说&#xff0c;最高为成交金额的3%&#xff0c;一般都会小于这个比例。最低交易佣金是5元起&a…

mac中的VirtualBox不能分配USB设备到虚拟电脑

mac中的VirtualBox不能分配USB设备到虚拟电脑 检查工具-> 扩展包是否安装 Oracle_VM_VirtualBox_Extension_Pack-7.0.14.vbox-extpack检查usb设备是否打开 检查权限 允许VirtualBox访问&#xff1a;在“安全性与隐私”窗口中&#xff0c;选择“隐私”标签。 在左侧的列表中…

微信过期文件怎么恢复?四个高招助你轻松解决(2024新版)

“微信的文件未下载的情况下过期了&#xff0c;平时微信也没有登录在电脑上&#xff0c;之前也没有进行过数据备份&#xff0c;如何找回这个文件啊&#xff01;&#xff01;感谢回答&#xff01;” “急求&#xff0c;当时忘记点击下载&#xff0c;现在急用微信文件下载不了&a…

Go gin框架(详细版)

目录 0. 为什么会有Go 1. 环境搭建 2. 单-请求&&返回-样例 3. RESTful API 3.1 首先什么是RESTful API 3.2 Gin框架支持RESTful API的开发 4. 返回前端代码 go.main index.html 5. 添加静态文件 main.go 改动的地方 index.html 改动的地方 style.css 改动…

【Linux网络编程】TCP协议

TCP协议 1.TCP协议段格式4位首位长度序号和确认序号16位窗口大小6个标志位 2.确认应答机制3.超时重传机制4.连接管理机制如何理解连接如何理解三次握手如何理解四次挥手 5.流量控制6.滑动窗口7.拥塞控制8.延迟应答9.捎带应答10.面向字节流11.粘包问题12.TCP异常情况13.TCP小结1…

通讯录的实现(单链表版本)

我们首先要知道通讯录的实现是基于单链表的基础上的&#xff0c;所以我们首先要搞懂单链表。&#xff08;注意&#xff1a;今天的代码量较多&#xff09;&#xff0c;但这不是阻挡我们前进的脚步&#xff0c;冲冲冲&#xff01;&#xff01;&#xff01; 单链表的简要概述 我们…

剖析 SPI 在 Spring 中的应用

一、概述 SPI&#xff08;Service Provider Interface&#xff09;&#xff0c;是Java内置的一种服务提供发现机制&#xff0c;可以用来提高框架的扩展性&#xff0c;主要用于框架的开发中&#xff0c;比如Dubbo&#xff0c;不同框架中实现略有差异&#xff0c;但核心机制相同…

构建第一个ArkTS应用之stateStyles:多态样式

Styles和Extend仅仅应用于静态页面的样式复用&#xff0c;stateStyles可以依据组件的内部状态的不同&#xff0c;快速设置不同样式。这就是我们本章要介绍的内容stateStyles&#xff08;又称为&#xff1a;多态样式&#xff09;。 概述 stateStyles是属性方法&#xff0c;可以…

如何发布自己的Python库?

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

【最新整理】3ds Max 大佬都在用的10款爆火插件推荐!

在3D建模和渲染领域&#xff0c;熟悉使用各种插件已经成为了大佬们的标配&#xff0c;而3ds Max作为最受欢迎的三维建模软件之一&#xff0c;更是有着丰富的插件资源。今天&#xff0c;小编将为大家盘点一下最新整理的10款爆火插件&#xff0c;这些插件不仅能够提升你的工作效率…

集合体系java

Collection:单列集合&#xff1a;每个元素只包含一个值 Collection集合存储的是地址 Collection的三种遍历方法如下 //迭代器是用来遍历集合的专用方式&#xff08;数组没有迭代器&#xff09;&#xff0c;在java中迭代器的代表是Iterator //boolean hasNext():询问当前位置…

10万字208道Java经典面试题总结(2024修订版)- SSM篇

&#x1f345; 作者简介&#xff1a;哪吒&#xff0c;CSDN2021博客之星亚军&#x1f3c6;、新星计划导师✌、博客专家&#x1f4aa; &#x1f345; 哪吒多年工作总结&#xff1a;Java学习路线总结&#xff0c;搬砖工逆袭Java架构师 &#x1f345; 技术交流&#xff1a;定期更新…