java.util.Stack的Iterator中是否有错误?

今天我试图推入java.util.Stack类,然后使用Iterator迭代(不使用pop)项目。 我期待着LIFO的财产,但很惊讶。

这是我正在尝试的代码。

 import java.util.*; import java.util.Stack; public class Main { public static void main(String[] args) { RobStack rstack = new RobStack(); // Correct Implementation Stack jstack = new Stack(); // 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使用Robert Sedgewick提供的实现来实现他的Algorithm类。 我发现Robert教授的实现工作正常,但java.util.Stack实现失败了。

它是一个错误还是设计

请参阅错误ID 4475301:RFE:java.util.Stack.iterator()以错误的方式迭代 。 这种行为是(糟糕的)设计。 Java的内置Stack迭代器方法inheritance自其他类,因此它们的行为与您期望的不同。

您应该使用Deque而不是Stack。

 Deque stack = new ArrayDeque(); 

请参阅Oracle Doc

原则上,你不应该迭代Stack ,但只能推到顶部或从顶部弹出。 至于实际实现,大多数语言(包括Java)使用另一种collection type来实现Stack 。 从严格要求的角度来看,它应该允许持续时间push, top and pop操作。

任何其他function(或本例中的错误)都应该被忽略,而不是依赖于编码。

也许,您可以使用.get()从上到下打印堆栈中的项目。

 Stack stack = new Stack(); 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 */ 

Eclipse Collections包含一个可变堆栈实现 ,其中迭代器从上到下返回值。 此代码打印3,2,然后打印1。

 MutableStack stack = ArrayStack.newStack(); stack.push(1); stack.push(2); stack.push(3); for (Iterator iterator = stack.iterator(); iterator.hasNext(); ) { Integer each = iterator.next(); System.out.println(each); } 

MutableStack不会扩展MutableCollectionCollection ,因此您无法从堆栈中间删除。 实现内部迭代模式的方法,如forEach()select()collect()anySatisfy()allSatisfy()等,也从上到下处理元素。 此代码打印相同的内容。

 stack.forEach(Procedures.println(System.out)); 

注意:我是Eclipse集合的提交者。

Stack从AbstractListinheritance.listIterator() ,允许逆序迭代。

 Stack stack = new Stack(); stack.push(1); stack.push(2); stack.push(3); for (ListIterator iterator = stack.listIterator(stack.size()); iterator.hasPrevious();) { Integer integer = iterator.previous(); System.out.println(integer); } // Output: 3 2 1