Java中栈实现怎么选?Stack、Deque、ArrayDeque、LinkedList(含常用Api积累)
目录
Java中的Stack类
不用Stack有以下两点原因
1、从性能上来说应该使用Deque代替Stack。
2、Stack从Vector继承是个历史遗留问题,JDK官方已建议优先使用Deque的实现类来代替Stack。
该用ArrayDeque还是LinkedList?
ArrayDeque与LinkList区别:
ArrayDeque:
LinkList:
结论
API积累
Deque中常用方法:
把Deque当栈用的时候:
把Deque当队列用的时候:
从上面(头部)插入:
从上面(头部)出来/观察:
从下面(尾部)插入:
从下面(尾部)出来/观察:
Java中的Stack类
Java中Stack类从Vector类继承,底层是用数组实现的线程安全的栈。栈是一种后进先出(LIFO)的容器,常用的操作push/pop/peek
。
不过Java中用来表达栈的功能(push/pop/peek
),更适用的是使用双端队列接口Deque,并用实现类ArrayDeque / LinkedList
来进行初始化。
Deque<Integer> stack = new ArrayDeque<>();
Deque<Integer> stack = new LinkedList<>();
不用Stack有以下两点原因
1、从性能上来说应该使用Deque代替Stack。
Stack和Vector都是线程安全的,其实多数情况下并不需要做到线程安全,因此没有必要使用Stack。毕竟保证线程安全需要上锁,有额外的系统开销。
2、Stack从Vector继承是个历史遗留问题,JDK官方已建议优先使用Deque的实现类来代替Stack。
Stack从Vector继承的一个副作用是,暴露了
set/get
方法,可以进行随机位置的访问,这与Stack只能从尾巴上进行增减的本意相悖。此外,Deque在转成ArrayList或者stream的时候保持了“后进先出”的语义,而Stack因为是从Vector继承,没有这个语义。
Stack<Integer> stack = new Stack<>(); Deque<Integer> deque = new ArrayDeque<>();stack.push(1); stack.push(2); deque.push(1); deque.push(2);System.out.println(new ArrayList<>(stack)); // [1,2] List<Integer> list1 = stack.stream().collect(Collectors.toList());//[1,2]// deque转成ArrayList或stream时保留了“后进先出”的语义 System.out.println(new ArrayList<>(deque)); // [2,1] List<Integer> list2 = deque.stream().collect(Collectors.toList());//[2,1]
该用ArrayDeque还是LinkedList?
ArrayDeque和LinkedList这两者底层,一个采用数组存储,一个采用链表存储;
ArrayDeque与LinkList区别:
ArrayDeque:
- 数组结构
- 插入元素不能为null
- 无法确定数据量时,后期扩容会影响效率
LinkList:
- 链表结构
- 插入元素能为null
- 无法确定数据量时,有更好表现
PS:这两者既可当成栈(仅支持在尾部加入或移除元素)使用;也可当成双端队列使用,即可以在队列的两端(头或尾)将元素加入或移除。
单次加入/移除元素的平均时间复杂度均为O(1)。
那么问题来了,在用作栈时到底用ArrayDeque好还是LinkedList好呢?
注意到ArrayDeque源码注释中有一句话:
This class is likely to be faster than {@link Stack} when used as a stack,
and faster than {@link LinkedList} when used as a queue.
ArrayDeque用作栈时比Stack快没有疑问,用作队列的时候似乎也会比LinkedList快!
笔者经过50W数据量的测试,发现两者性能基本接近,ArrayDeque
平均耗时在18-24ms,LinkedList
耗时平均在20-28ms。
如果数据量上升到100W的话,ArrayDeque
的优势会更明显。
结论:ArrayDeque会略胜一筹,不过差别通常可以忽略
public static void main(String[] args) {int length = 500000;int max = length;// 生成一个长度为length,值从1~max的随机数组int[] data = new RandomIntArray(length,1,length,max).next();int loopCount = 10;long t1, t2;t1 = System.currentTimeMillis();for (int i = 0; i < loopCount; i++) {// testArrayDeque(data);testLinkedList(data);}t2 = System.currentTimeMillis();// 测试loopCount次取平均结果System.out.println("timeTaken: " + String.format("%.1f", (t2-t1)/(double)loopCount));
}public static void testArrayDeque(int[] data) {int length = data.length;Deque<Integer> stack = new ArrayDeque<>();for (int i = 0; i < length/2; i++) {stack.push(data[i]);stack.push(data[i+1]);stack.pop();stack.push(stack.peek()+1);}
}public static void testLinkedList(int[] data) {int length = data.length;Deque<Integer> stack = new LinkedList<>();for (int i = 0; i < length/2; i++) {stack.push(data[i]);stack.push(data[i+1]);stack.pop();stack.push(stack.peek()+1);}
}
结论
ArrayDeque会略胜一筹,不过差别通常可以忽略。
经过性能对比,笔者更倾向于使用ArrayDeque
来表达Java中的栈功能。
API积累
Deque中常用方法:
以这2个为基础整出来的Deque除了结构不一样,方法都一样的。
把Deque当栈用的时候:
入栈 | push(E e) |
出栈 | poll() / pop() 后者在栈空的时候会抛出异常,前者返回null |
查看栈顶 | peek() 为空时返回null |
把Deque当队列用的时候:
入队 | offer(E e) |
出队 | poll() 为空时返回null |
查看队首 | peek() 为空时返回null |
有些时候需要进行一些骚操作的时候(比如取得栈底元素,取得队尾元素),这些常规操作就不能满足了。
下面就是Deque中一些更详细的方法。
从上面(头部)插入:
方法名 | 作用 |
---|---|
void addFirst(E e) | 将指定的元素插入此双端队列的前面 ,空间不足抛异常 |
boolean offerFirst(E e) | 将指定的元素插入此双端队列的前面 ,空间不足插入失败返回回false |
void push(E e) | 将指定的元素插入此双端队列的前面 ,空间不足抛异常 |
从上面(头部)出来/观察:
方法名 | 作用 |
---|---|
E removeFirst() | 检索并删除第一个元素,为空时抛出异常 |
E remove() | 和removeFirst一样 检索并删除第一个元素,为空时抛出异常 |
E pop() | 和removeFirst一样 检索并删除第一个元素,为空时抛出异常 |
E pollFirst() | 检索并删除第一个元素 ,为空时返回null |
E poll() | 和pollFirst一样 检索并删除第一个元素 ,为空时返回null |
E getFirst() | 只看看第一个元素 ,不出来,为空就抛异常 |
E element() | 和getFirst一样 只看看第一个元素 ,不出来,为空就抛异常 |
E peekFirst() | 只看看第一个元素 ,不出来,为空时返回null |
E peek() | 和peekFirst一样 只看看第一个元素 ,不出来,为空时返回null |
从下面(尾部)插入:
方法名 | 作用 |
---|---|
void addLast(E e) | 将指定的元素插入此双端队列的后面 ,空间不足抛异常 |
boolean offerLast(E e) | 将指定的元素插入此双端队列的后面,空间不足返回false |
boolean add(E e) | 将指定的元素插入此双端队列的后面,空间不足抛异常 |
boolean offer(E e) | 将指定的元素插入此双端队列的后面,空间不足返回false |
从下面(尾部)出来/观察:
方法名 | 作用 |
---|---|
E removeLast() | 检索并删除最后一个元素,为空时抛出异常 |
E pollLast() | 检索并删除最后一个元素 ,为空时返回null |
E getLast() | 只看看最后一个元素 ,不出来,为空就抛异常 |
E peekLast() | 只看看最后一个元素 ,不出来,为空时返回null |
相关文章:
Java中栈实现怎么选?Stack、Deque、ArrayDeque、LinkedList(含常用Api积累)
目录 Java中的Stack类 不用Stack有以下两点原因 1、从性能上来说应该使用Deque代替Stack。 2、Stack从Vector继承是个历史遗留问题,JDK官方已建议优先使用Deque的实现类来代替Stack。 该用ArrayDeque还是LinkedList? ArrayDeque与LinkList区别࿱…...
雷达分辨率单元、单向/双向雷达方程、天气雷达方程简介
一、点状目标 如果两个点状目标在一个分辨率单元中,经典脉冲雷达只能看到一个目标。 点状目标 二、雷达距离分辨率 对于简单的键控开/关脉冲调制: 对于使用脉冲内调制的雷达,距离分辨率取决于压缩脉冲的脉冲持续时间。脉冲压缩比(PCR)取决于传输带宽BWtx,即距离分辨率取…...
RabbitMQ之Fanout(扇形) Exchange解读
目录 基本介绍 适用场景 springboot代码演示 演示架构 工程概述 RabbitConfig配置类:创建队列及交换机并进行绑定 MessageService业务类:发送消息及接收消息 主启动类RabbitMq01Application:实现ApplicationRunner接口 基本介绍 Fa…...
Redisson—分布式集合详述
7.1. 映射(Map) 基于Redis的Redisson的分布式映射结构的RMap Java对象实现了java.util.concurrent.ConcurrentMap接口和java.util.Map接口。与HashMap不同的是,RMap保持了元素的插入顺序。该对象的最大容量受Redis限制,最大元素数…...
开发做前端好还是后端好?这是个问题!
前言 随着互联网的快速发展,越来越多的人选择从事Web开发行业,而Web开发涉及到前端和后端两个方面,相信许多人都曾经对这两个方面进行过探究。而且编程世界就像一座大城市,前端开发和后端开发就像城市的两个不同街区。作为初学者&…...
运行huggingface Kosmos2报错 nameerror: name ‘kosmos2tokenizer‘ is not defined
尝试运行huggingface上的Kosmos,https://huggingface.co/ydshieh/kosmos-2-patch14-224失败,报错: nameerror: name kosmos2tokenizer is not defined查看报错代码: vi /root/.cache/huggingface/modules/transformers_modules/ydshieh/kosmos-2-patch14-224/48e3edebaeb…...
吃鸡玩家必备神器!一站式提升战斗力、分享干货!
大家好,我是吃鸡玩家。在这个视频中,我要分享一个让你瞬间提高战斗力的神器,同时让你享受到顶级游戏作战干货的盛宴!让我们一起来了解吧! 首先,我们推荐绝地求生作图工具。通过这款工具,你可以轻…...
【maven】idea中基于maven-webapp骨架创建的web.xml问题
IDEA中基于maven-webapp骨架创建的web工程,默认的web.xml是这样的。 <!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name…...
【算法题】2034. 股票价格波动
插: 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 坚持不懈,越努力越幸运,大家一起学习鸭~~~ 题目: 给你一支股票价格的数据流。数据流…...
APSIM模型】作物模型应用案例
APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生长模拟模型之一。APSIM模型有Classic和Next Generation两个系列模型,能模拟几十种农作物、牧草和树木的土壤-植物-大气过程,被广泛应用于精细农业、水肥管理、气候变化、粮食安…...
io_uring之liburing库安装
手动编译和安装 liburing: 1.首先,从 liburing 的 GitHub 仓库中获取源代码。您可以使用以下命令克隆仓库: git clone https://github.com/axboe/liburing.git2.进入 liburing 目录: cd liburing3.运行configure ./configure …...
Python WebSocket自动化测试:构建高效接口测试框架!
为了更高效地进行WebSocket接口的自动化测试,我们可以搭建一个专门的测试框架。本文将介绍如何使用Python构建一个高效的WebSocket接口测试框架,并重点关注以下四个方面的内容:运行测试文件封装、报告和日志的封装、数据驱动测试以及测试用例…...
MySQL数据库——SQL优化(1)-介绍、插入数据、主键优化
目录 介绍 插入数据 Insert 大批量插入数据 主键优化 数据组织方式 页分裂 页合并 索引设计原则 介绍 SQL优化将分为下面几个部分进行学习: 插入数据主键优化order by优化group by优化limit优化count优化update优化 首先就先来看第一方面, 插…...
Flink---10、处理函数(基本处理函数、按键分区处理函数、窗口处理函数、应用案例TopN、侧输出流)
星光下的赶路人star的个人主页 我的敌手就是我自己,我要他美好到能使我满意的程度 文章目录 1、处理函数1.1 基本处理函数(ProcessFunction)1.1.1 处理函数的功能和使用1.1.2 ProcessFunction解析1.1.3 处理函数的分类 1.2 按键分区处理函数&…...
多种方案教你彻底解决mac npm install -g后仍然不行怎么办sudo: xxx: command not found
问题概述 某些时候我们成功执行了npm install -g xxx,但是执行完成以后,使用我们全局新安装的包依然不行,如何解决呢? 解决方案1: step1: 查看npm 全局文件安装地址 XXXCN_CXXXMD6M ~ % npm list -g …...
斐波那契数列 JS
问题: 给出一个数字,找出它是斐波那契数列中的第几个数 斐波那契数列 [1, 1, 2, 3, 5, 8, 13, ...],后一个数字是前两个数字之和 输入的数字大于等于 2 如果输入数字不存于斐波那契数列中,返回 -1 function demo(num) {//初始数据…...
IP 地址的分类
IP地址是用于标识计算机或设备在互联网上的位置的一种地址。IP地址通常根据其范围和用途分为不同的分类,主要包括以下几种: IPv4地址(Internet Protocol version 4): IPv4地址是32位二进制数,通常以点分十…...
CDN网络基础入门:CDN原理及架构
背景 互联网业务的繁荣让各类门户网站、短视频、剧集观看、在线教育等内容生态快速发展,互联网流量呈现爆发式增长,自然也面临着海量内容分发效率上的挑战,那么作为终端用户,我们获取资源的体验是否有提升呢? 答案是…...
李沐深度学习记录2:10多层感知机
一.简要知识记录 x.numel():看向量或矩阵里元素个数 A.sum():向量或矩阵求和,axis参数可对某维度求和,keepdims参数设置是否保持维度不变 A.cumsum:axis参数设置沿某一维度计算矩阵累计和x*y:向量的按元素乘法 torch.…...
Python标准库中内置装饰器@staticmethod@classmethod
装饰器是Python中强大而灵活的功能,用于修改或增强函数或方法的行为。装饰器本质上是一个函数,它接受另一个函数作为参数,并返回一个新的函数,通常用于在不修改原始函数代码的情况下添加额外的功能或行为。这种技术称为元编程&…...
MySQL8 间隙锁在11种情况下的锁持有情况分析
测试环境及相关必要知识 测试环境为mysql 8 版本 间隙锁(Gap Lock):用于锁定索引范围之间的间隙,防止其他事务在此间隙中插入新记录。间隙锁主要用于防止幻读问题。 在可重复读的隔离级别下默认打开该锁机制,解决幻…...
C# 图片按比例进行压缩
1、对图片进行压缩,保存在本地 对于一个200k的png文件按0.6的缩放比例进行压缩,压缩后的大小为20k左右 对于一个80k的jpg文件按0.6的缩放比例压缩,压缩后为13k左右 public void imageZoom(string name, Double zoomScale){Bitmap btImage …...
猜猜 JavaScript 输出:(! + [] + [] + ![]).length
一起猜 最近看到一个很有意思的题,直接来看,下面这段代码的打印结果是什么? console.log((! [] [] ![]).length) 猜猜看,你的答案是什么,打在评论区。 我的答案是 undefined,正如我的英文名 为什么呢&a…...
MTK Android12静默安装接口
该文档就是在android12系统上提供一个广播接收器,app端发送一个广播,并且带入apk的地址就可以实现安装 1、广播注册 frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java 首先要导入的依赖 import android.app.P…...
基于电容电流前馈与电网电压全前馈的三相LCL并网逆变器谐波抑制Simulink仿真
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Python数据攻略-Pandas与统计数据分析
统计学在数据分析中到底有多重要?在数据分析的世界里,统计学扮演着一角色。想象一下你是《三国志》游戏的数据分析师,任务是找出哪个武将最受玩家欢迎,哪些战役最具挑战性等。 你怎么做呢?这就需要统计学的力量了。 文章目录 基础统计方法描述性统计方差和标准差相关性和…...
【gcc】RtpTransportControllerSend学习笔记 1
本文是大神 https://www.cnblogs.com/ishen 的文章的学习笔记。主要是大神文章: webrtc源码分析(8)-拥塞控制(上)-码率预估 的学习笔记。大神的webrtc源码分析(8)-拥塞控制(上)-码率预估 详尽而具体,堪称神作。因为直接看大神的文章,自己啥也没记住,所以同时跟着看代码。跟…...
若依分离版-前端使用
1 执行 npm install --registryhttps://registry.npm.taobao.org,报错信息如下 npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: ktg-mes-ui3.8.2 npm ERR! Found: vue2.6.12 npm ERR! node_modu…...
微信小程序-2
微信开发文档 https://developers.weixin.qq.com/miniprogram/dev/framework/ 一、app.js中的生命周期函数与globalData(全局变量) 指南 - - - 小程序框架 - - - 注册小程序 删除app.js里的东西,输入App回车,调用生命周期 选项 - - - 重新打开此项目…...
卷积神经网络的发展历史-ResNet
ResNet的产生 2015 年,Kaiming He 提出了ResNet(拿到了 2016 年 CVPR Best Paper Award),不仅解决了神经网络中的退化问题还在同年的ILSVRC和COCO 竞赛横扫竞争对手,分别拿下分类、定位、检测、分割任务的第一名。 R…...
asp.net 4.0网站建设基础教程/东莞网站建设快速排名
2019独角兽企业重金招聘Python工程师标准>>> 上篇文章介绍了springBoot的各种优点,嗯,它很容易就能搭建一个web应用,那么具体怎么做呢? 那么我们简单的搭建一个hello 的web应用,这应用非常简单,…...
南昌网站小程序开发/seo公司运营
一:依赖关系 1:依赖和血缘关系介绍 rdd.todebugstring:打印血缘关系 rdd.dependencies:打印依赖关系 2:保存血缘关系 3:OneToOne依赖---窄依赖 4:shuffle依赖--宽依赖 新的RDD的一个分区的数据…...
网站建设与管理教案/产品推广方案ppt模板
程序猿和架构师都应该了解“康威定律”(Conways law) 什么是康威定律 康威定律是一句格言,指出组织设计系统来反映他们自己的沟通结构。它以计算机程序员梅尔文康威的名字命名,他于1967年提出了这个想法。他最初的措辞是: organizations wh…...
像试淘网网站怎么建设/seo快速软件
最近在技术上确实是没有长进,之前孜孜不倦求知欲望,现在其实对技术提不起兴趣了,其实准确说不是没有兴趣,应该是没有激情,或许是因为一直过于劳累的原因,现在不管是身体上,还是精神上都显出过度疲劳的状态.真的希望能够休息一段时间,放开所有的烦恼,回家看看,去看看美丽的大自然…...
jetpack wordpress/腾讯企点官网
具体请看这里→http://www.k-zone.cn/zblog/post/log-2006-11-21-001.html 呵呵,难得大家对这篇文章感兴趣。今天我就跟大家讨论一下FlexCSharp这种架构具体的实现办法。1、 开发环境准备。在上一篇我已经说明了,开发环境是vs2005Flex2,也就是…...
wordpress html代码/百度图片识别在线识图
electronJS 是一个跨平台软件开发工具,使用 JavaScript, HTML 和 CSS 构建跨平台的桌面应用。由于使用了HTML 所以开发的界面更加丰富,美观和快捷。缺点是哪怕是一个Hello the world,也有几百M,程序很庞大。个人觉得electronJS 适…...