今天我尝试推入java.util.Stack
类,然后使用Iterator
通过项目迭代(不使用pop)。我期待LIFO的财产,但很惊讶。
这是我正在尝试的代码。
import java.util.*;
import java.util.Stack;
public class Main {
public static void main(String[] args) {
RobStack<Integer> rstack = new RobStack<Integer>(); // Correct Implementation
Stack<Integer> jstack = new Stack<Integer>(); // Default Java Implementation
rstack.push(0); jstack.push(0);
rstack.push(1); jstack.push(1);
rstack.push(2); jstack.push(2);
rstack.push(3); jstack.push(3);
System.out.print("Algo Stack: ");
for (int i : rstack)
System.out.print(i + " ");
System.out.print("\nJava Stack: ");
for (int i : jstack)
System.out.print(i + " ");
}
}
上述程序的输出如下:
Algo Stack: 3 2 1 0
Java Stack: 0 1 2 3
在上面的代码jstack
中使用默认的Java实现,而rstack
使用implementation provided by Robert Sedgewick作为他的Algorithm类。我发现Robert教授的实现工作正常,但java.util.Stack
实现失败了。
是错误还是设计?
答案 0 :(得分:29)
见Bug ID 4475301 : RFE: java.util.Stack.iterator() iterates the wrong way。这种行为是(坏的)设计。 Java的内置Stack
迭代器方法继承自其他类,因此它们的行为与您期望的不同。
答案 1 :(得分:9)
答案 2 :(得分:2)
原则上,你不应该迭代Stack
,而只能推到顶部或从顶部弹出。至于实际实现,大多数语言(包括Java)使用另一个collection type
来实现Stack
。从严格的要求角度来看,它应该允许恒定的时间push, top and pop
操作。
任何其他功能(或本例中的错误)都应该被忽略,而不是依赖于编码。
答案 3 :(得分:2)
也许,您可以使用.get()从上到下打印堆栈中的项目。
Stack<Integer> stack = new Stack<Integer>();
stack.push(3);
stack.push(2);
stack.push(1);
// print from top to bottom
for(int i = stack.size() - 1; i >= 0; i--){
System.out.println(stack.get(i));
}
/*
output
1
2
3
*/
答案 4 :(得分:1)
Eclipse Collections包含mutable stack implementation,其中迭代器从上到下返回值。此代码打印3,2,然后1。
MutableStack<Integer> stack = ArrayStack.newStack();
stack.push(1);
stack.push(2);
stack.push(3);
for (Iterator<Integer> iterator = stack.iterator(); iterator.hasNext(); )
{
Integer each = iterator.next();
System.out.println(each);
}
MutableStack
不会扩展MutableCollection
或Collection
,因此您无法从堆栈中间删除,例如。实现内部迭代模式(如forEach()
,select()
,collect()
,anySatisfy()
,allSatisfy()
等的方法也会从上到下处理元素。此代码打印相同的内容。
stack.forEach(Procedures.println(System.out));
注意:我是Eclipse集合的提交者。
答案 5 :(得分:0)
Stack从 AbstractList 继承 .listIterator(),它允许逆序迭代。
Stack<Integer> stack = new Stack<Integer>();
stack.push(1);
stack.push(2);
stack.push(3);
for (ListIterator<Integer> iterator = stack.listIterator(stack.size()); iterator.hasPrevious();) {
Integer integer = iterator.previous();
System.out.println(integer);
}
// Output: 3 2 1
答案 6 :(得分:0)