我有一个包含3个项目的Stack,我想在每个项目上循环。如果我这样做:
public class Main {
public static void main(String[] args) {
Stack<Integer> s = new Stack<>();
s.add(1);
s.add(2);
s.add(3);
for (Integer num = s.pop(); !s.isEmpty(); num = s.pop()) {
System.out.println(num);
}
}
}
则它只打印出3和2,而不打印出1。为什么?
for
循环弹出堆栈,如果堆栈为空则退出循环。
for (Integer num = s.pop(); !s.isEmpty(); num = s.pop()) {
System.out.println(num);
}
换句话说,num = s.pop()
在测试!s.isEmpty()
之前运行。因此,在最后一次迭代中,堆栈是空的,因此循环体不会执行。
对此有很多不同的方法。你可以做的一件事是使用while
循环:
while (!s.isEmpty()) {
System.out.println(s.pop());
}
For循环由3个表达式组成:初始化、终止、增量:
for (initialization; termination; increment) {
//
}
- 初始化仅执行一次
- 每次迭代都执行termination
- 每次迭代执行增量
在您的情况下,在第一次迭代中,您从堆栈中检索了两次,因此出现了非打印元素的问题。你可能想知道为什么它打印3,2
而不是2,1
?这是因为increment表达式在循环的每次迭代后被调用。
所有的部分都是可选的,所以你可以这样迭代:
for (; ; ) {
System.out.println(s.pop());
}
并且您最终将在尝试从已经空的堆栈中弹出元素时使用CCD_ 7。
因此,用for循环迭代堆栈的最基本方法是使用termination语句作为";"安全检查":
for (; !s.isEmpty(); ) {
System.out.println(s.pop());
}
这基本上是一种更复杂和违反直觉的方式来编写while
-循环:
while (!s.isEmpty()) {
System.out.println(s.pop());
}
文档:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html
原因是在计算条件时堆栈已经为空。
几个选项(不是全部(如何正确弹出和打印所有项目:
- 循环时执行。如注释中所述,如果堆栈最初为空,将抛出
EmptyStackException
do {
System.out.println(s.pop());
} while (!s.empty());
- While循环
while (!s.empty()) {
System.out.println(s.pop());
}