簡體   English   中英

java.util.Stack 的迭代器中是否存在錯誤?

[英]Is there a bug in java.util.Stack's Iterator?

今天我試圖推入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使用Robert Sedgewick為其算法類提供實現 我發現 Robert 教授的實現工作正常,但java.util.Stack實現失敗。

這是一個錯誤還是設計使然

請參閱錯誤 ID 4475301:RFE:java.util.Stack.iterator() 以錯誤的方式迭代 這種行為是(糟糕的)設計造成的。 Java 的內置Stack迭代器方法是從其他類繼承而來的,因此它們的行為與您預期的不同。

您應該使用 Deque 而不是 Stack。

Deque<Integer> stack = new ArrayDeque<Integer>();

請參閱 Oracle 文檔

原則上,您不應該迭代Stack ,而應該只推入頂部或從頂部彈出。 至於實際實現,大多數語言,包括 Java,使用另一種collection type來實現Stack 從嚴格的要求來看,它應該允許持續時間push, top and pop操作。

任何附加功能(或在這種情況下的錯誤)都應該被忽略,而不是依賴於編碼。

也許,您可以使用 .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
*/

Eclipse Collections包括一個可變堆棧實現,其中迭代器從上到下返回值。 此代碼打印 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不擴展MutableCollectionCollection ,因此您無法從堆棧中間刪除。 實現諸如forEach()select()collect()anySatisfy()allSatisfy()等內部迭代模式的方法也從上到下處理元素。 此代碼打印相同的內容。

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

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

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

您可以使用LinkedList並使用pushpop方法來代替Stack

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM