Java集合——13.使用Stack
Java的栈(Stack)
栈的特性
与队列(Queue)的"先进先出(FIFO)"不同,栈(Stack)是一种遵循后进先出(LIFO,Last In First Out) 原则的数据结构。可以形象地理解为一叠盘子:最后放上的盘子总是最先被拿走。
Java中栈的方法
Java标准库中并没有专门的Stack接口,而是通过Deque(双端队列)来模拟栈的功能。这是因为Java早期提供的Stack类是一个遗留类,存在设计缺陷,不推荐使用。
| 栈操作 | Deque方法 | 等效方法 |
|---|---|---|
| 压栈 | push(E e) |
addFirst(E e) |
| 出栈 | pop() |
removeFirst() |
| 查看栈顶 | peek() |
peekFirst() |
使用Deque作为栈时,尽可能只调用push()、pop()和peek()方法,避免使用Deque的其他方法,以保证代码的清晰性。
栈的典型应用场景
1. 方法调用栈
JVM(Java虚拟机)使用栈来管理方法调用:
- 每次调用方法时,JVM会将方法参数、返回地址等信息压入栈中
- 方法执行完毕后,这些信息会被出栈,程序回到调用点继续执行
如果方法嵌套调用层数过深(如无限递归),会导致栈溢出,抛出StackOverflowError:
public class StackOverflowExample {
public static void main(String[] args) {
recursiveCall();
}
static void recursiveCall() {
recursiveCall(); // 无限递归导致栈溢出
}
}
2. 进制转换
栈非常适合实现整数的进制转换。以十进制转十六进制为例,算法步骤如下:
- 将整数除以目标进制(如16),得到商和余数
- 将余数压栈
- 用商重复步骤1,直到商为0
- 将栈中元素依次出栈,组成转换后的字符串
实现代码:
import java.util.Deque;
import java.util.LinkedList;
public class HexConverter {
public static String toHex(int n) {
if (n == 0) {
return "0";
}
Deque<Character> stack = new LinkedList<>();
char[] hexDigits = "0123456789ABCDEF".toCharArray();
while (n != 0) {
int remainder = n % 16;
stack.push(hexDigits[remainder]);
n = n / 16;
}
StringBuilder sb = new StringBuilder();
while (!stack.isEmpty()) {
sb.append(stack.pop());
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(toHex(12500)); // 输出30D4
}
}
3. 表达式计算
栈是编译原理中处理表达式的重要工具,主要用于:
- 将中缀表达式(如
1 + 2 * (9 - 5))转换为后缀表达式(如1 2 9 5 - * +) - 计算后缀表达式的值
计算后缀表达式的步骤:
- 扫描表达式,遇到数字则压栈
- 遇到运算符则弹出栈顶两个元素,计算结果后将结果压栈
- 表达式扫描完毕后,栈中剩余的元素即为计算结果
示例:计算1 2 9 5 - * +
import java.util.Deque;
import java.util.LinkedList;
public class PostfixCalculator {
public static int calculate(String[] tokens) {
Deque<Integer> stack = new LinkedList<>();
for (String token : tokens) {
switch (token) {
case "+":
int b = stack.pop();
int a = stack.pop();
stack.push(a + b);
break;
case "-":
b = stack.pop();
a = stack.pop();
stack.push(a - b);
break;
case "*":
b = stack.pop();
a = stack.pop();
stack.push(a * b);
break;
case "/":
b = stack.pop();
a = stack.pop();
stack.push(a / b);
break;
default:
stack.push(Integer.parseInt(token));
}
}
return stack.pop();
}
public static void main(String[] args) {
String[] postfix = {"1", "2", "9", "5", "-", "*", "+"};
System.out.println(calculate(postfix)); // 输出9
}
}
总结
- 掌握栈的特性和主要操作方法:压栈(push)、出栈(pop)和查看栈顶(peek)
- 在Java中,我们使用
Deque接口及其实现类(如LinkedList、ArrayDeque)来模拟栈。 - 栈有广泛应用,
- 栈在计算机科学中应用广泛,包括JVM方法调用、进制转换、表达式计算等场景。
Java集合——13.使用Stack的更多相关文章
- Java 集合系列 06 Stack详细介绍(源码解析)和使用示例
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 13 WeakHashMap
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 09 HashMap详细介绍(源码解析)和使用示例
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 10 Hashtable详细介绍(源码解析)和使用示例
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 17 TreeSet
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 16 HashSet
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 15 Map总结
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 14 hashCode
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 12 TreeMap
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 11 hashmap 和 hashtable 的区别
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
随机推荐
- gcc、g++命令
gcc 与 g++ 分别是 gnu 的 c & c++ 编译器 gcc/g++ 在执行编译工作的时候,总共需要4步: 1.预处理,生成 .i 的文件[预处理器cpp] 2.将预处理后的文件转换 ...
- 我们不可能永远都在救火 ——Scrum中技术债务“偿还”指南
技术债务是指开发人员为了加速软件开发,在应该采用最佳方案时进行了妥协,改用了短期内能加速软件开发的方案,以至于未来给自己带来额外的开发负担. 软件工程师 Ward Cunningham首次将技术的复杂 ...
- 现在的AI工具还能写剧本杀了?
本文由 ChatMoney团队出品 近年来,剧本杀作为一种新兴社交游戏,收到了越来越多人的喜爱,它不仅需要玩家们发挥自身演技,还需运用逻辑思维推理,分析所获得的线索,找出案件真凶.然而你是否想过,你在 ...
- Spring注解中@Resource和@Authwired的区别
Spring注解中@Resource和@Authwired的区别 @Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 by ...
- 看PHP7底层源码与设计 读后感
对PHP的理解 读完这本书以后,发现自己好像不会PHP,自己知识PHP代码的搬运工,对数组的实现,内存管理,生命周期,垃圾回收,面向对象,Zend虚拟机这些知识点,这些都不知道,现在也说不上来,具体的 ...
- 【图书预售】清华大学出版社出版的《JMeter核心技术、性能测试与性能分析》开始预售了
<JMeter核心技术.性能测试与性能分析>是一本由清华大学出版社出版的图书,JMeter是一款基于Java的压力测试工具,可用于对服务器.网络或对象模拟巨大的负载,在不同压力类别下测试它 ...
- 为什么PostgreSQL不自动缓存执行计划?这可能是最硬核的优化解读
为什么PostgreSQL不自动缓存执行计划?这可能是最硬核的优化解读 前言 在数据库性能方面,查询语句的执行计划是最关键的因素之一.每当数据库接收到一个查询时,它必须决定如何以最有效的方式执行该查询 ...
- Sql server 游标处理数据
https://blog.csdn.net/sinat_28984567/article/details/79811887 DECLARE @id INT , @name NVARCHAR(50) - ...
- 如何把数据库中的多个关联字段快速生成思维导图(excel如何将内容快速生成思维导图)
本次记录绝对干货 一:要求 今天遇到的需求,又是一件费力的活,要求如下:数据库中有三个字段,分别是一级分类,二级分类,三级分类,三个字段是级别关系,三级分类一共有上百个,现要求用思维导图的方式展示出来 ...
- 在 django-ninja 中实现类似腾讯阿里云的应用鉴权机制
前言 本文章介绍如何使用基于 AppClient 模型的 Django-Ninja API 鉴权机制. 这也是上次说的中台项目衍生物 中台项目相关的文章,我大概还会再写一篇 这个系列的文章注定是没什么 ...