BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #62173同步于 2019/6/18
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

【问题】这是一个关于Java Stack栈 空栈异常的问题

xiaoxiaohai
2019/6/18镜像同步8 回复
默认堆栈至少存有一个"(",且所存元素类型均为String String temp; while((temp=s1.pop())!="("){ s2.add(temp); } 这里报了空栈异常 String temp; while(!(temp=s1.pop()).equals("(")){ s2.add(temp); } 下面的操作方式则没有报 具体问题就涉及了中缀表达式转为后缀表达式的算法 附上源代码和解题思路图片 不知道不知是否是Java程序执行顺序的问题?
订阅后,新回复会通过你的通知中心匿名送达。
8 条回复
xuanyu66机器人#1 · 2019/6/18
无图言X
yuluo114机器人#2 · 2019/6/18
!= 比较地址,第一个while条件是不是一直为false
xiaoxiaohai机器人#3 · 2019/6/18
【 在 xuanyu66 的大作中提到: 】 : 无图言X 附件(1.7MB) 1.bmp
xiaoxiaohai机器人#4 · 2019/6/18
【 在 yuluo114 的大作中提到: 】 : != 比较地址,第一个while条件是不是一直为false public static void main(String[] args) { Stack<String> stack =new Stack<>(); stack.push("("); String temp; System.out.println((temp=stack.pop())=="("); String str ="("; System.out.println(str=="("); } 简单地跑了一下,结果都是true,貌似地址啥的本身由于Java对于"("的hashcode是一样的,不是地址的原因
xiaoxiaohai机器人#5 · 2019/6/18
【 在 xiaoxiaohai 的大作中提到: 】 : [size=2]默认堆栈至少存有一个"(",且所存元素类型均为String : String temp; : while((temp=s1.pop())!="("){ : ................... 附件(7.5KB) PolandNotation.java 源代码 第140行处 忘记上传啦
yuluo114机器人#6 · 2019/6/18
s1中是String对象,和常量用!=比较的结果是true 【 在 xiaoxiaohai (湖人总冠军~) 的大作中提到: 】 : public static void main(String[] args) { : Stack<String> stack =new Stack<>(); : stack.push("("); : ...................
xuanyu66机器人#7 · 2019/6/18
https://www.cnblogs.com/guoziyi/p/5993085.html String是不可变对象,最好是用equals。平常可以用==的原因是java为了复用String,做了优化,会把String放入常量池共用。但是如果你显式的调用new String()或者拼接两个字符串,那会在堆上生成新对象,而不会复用常量池,因此这时候==无效。 我看你的代码里是用拼接生成的String,这样会生成很多个"("对象。 题外话,如果在循环中拼接String对象,java推荐用StringBuilder,这样多次循环中只会有一个对象,节省空间。 一句话,尽量规范使用equals比较String。
xiaoxiaohai机器人#8 · 2019/6/19
【 在 xuanyu66 的大作中提到: 】 : https://www.cnblogs.com/guoziyi/p/5993085.html : String是不可变对象,最好是用equals。平常可以用==的原因是java为了复用String,做了优化,会把String放入常量池共用。但是如果你显式的调用new String()或者拼接两个字符串,那会在堆上生成新对象,而不会复用常量池,因此这时候==无效。 : 我看你的代码里是用拼接生成的String,这样会生成很多个"("对象。 : ................... 我今日再次检查代码,的确就是常量池影响了栈遍历的异常,并不是Stack栈特性所致(昨日我的思路不对,这点在回复另一个童鞋的简单测试中体现)。实际上进行多次stack.push("(")操作,其的“地址”都是一样的,所以.equals()方法和==并没有不同之处; 经过分析,是由于增强for循环中的String类型临时变量item,其为"("时,与(temp=s1.pop())!="("中后者的"("地址不同;此说法的证明方式:源代码131行处改成s1.push("(")就没有上述原因 附件(7.5KB) PolandNotation.java 总结: String对象还是.equal靠谱,虽然Java有常量池的特性,但是总有特例;还有for循环里的确不要用String类型的拼接[ema11]