Java双栈实现MinStack时s.peek()==ss.peek()判断不生效原因
问题描述
采用双栈思路实现最小栈时,pop方法中的相等判断出现异常:
- 两栈栈顶元素值相同的情况下,直接使用
s.peek() == ss.peek()作为if判断条件会返回false,对应分支始终无法触发执行 - 若先将两个peek()的返回值赋值给int基本类型变量a、b,再通过
a == b判断,却可以正常进入分支
对应问题代码如下:
class MinStack { Stack <Integer> s = new Stack<>(); Stack <Integer> ss = new Stack<>(); public MinStack() { } public void push(int val) { if(ss.isEmpty() || val<=ss.peek()) ss.push(val); s.push(val); return; } public void pop() { if(s.isEmpty()) return; int a = s.peek(); int b = ss.peek(); if(s.peek() == ss.peek()){ //this does not work ss.pop(); } if(a == b){ ss.pop(); } s.pop(); return; } public int top() { if(s.isEmpty()) return -1; return s.peek(); } public int getMin() { if(ss.isEmpty()) return -1; return ss.peek(); } } /** * Your MinStack object will be instantiated and called as such: * MinStack obj = new MinStack(); * obj.push(val); * obj.pop(); * int param_3 = obj.top(); * int param_4 = obj.getMin(); */
原因解析
判断失效的核心原因是包装类引用比较和基本类型值比较的规则差异,具体说明:
- 栈的泛型定义为
Integer,因此peek()方法返回的是Integer包装类对象,而非int基本类型值 - 直接对两个
peek()返回值用==比较时,本质是对比两个对象的内存地址,而非对象存储的数值。Java仅对[-128, 127]区间的Integer做了常量池缓存,超出这个范围的数值在自动装箱时会生成独立的新对象,哪怕数值完全相同,两个对象的内存地址也不一致,会导致==判断返回false - 将peek返回值赋值给int类型变量时,会触发自动拆箱,直接提取Integer对象内部存储的原始int值,此时
a == b是两个基本类型的数值比较,结果只和值是否相等有关,因此能正常触发分支
修复方案
可以选择任意一种写法替换原失效判断:
- 手动拆箱为基本类型后比较:
(int)s.peek() == (int)ss.peek() - 调用包装类的值比较方法:
s.peek().equals(ss.peek())
内容的提问来源于stack exchange,提问作者Dizzy
相关产品推荐
相关产品推荐

