2013-02-15 12 views
17

各構文でJavaのforを使用する場合、Stackは、出力された要素に対してLIFOの順序付けを使用しません。次のコードを考えてみましょう:スタック、foreach、間違った順序?

import java.util.Queue; 
import java.util.Stack; 
import java.util.LinkedList; 

public class QueueStackTest { 
    private static int[] numbers = {1, 2, 3, 4, 5}; 

    public static void main(String[] args) { 
    Stack<Integer> s = new Stack<Integer>(); 
    Queue<Integer> l = new LinkedList<Integer>(); 

    for (int i : numbers) { 
     s.push(i); 
     l.offer(i); 
    } 

    System.out.println("Stack: "); 
    for(Integer i : s) { 
     System.out.println(i); 
    } 

    System.out.println(); 
    System.out.println("Queue:"); 
    for(Integer i : l) { 
     System.out.println(i); 
    } 
    } 
} 

出力:

Stack: 
1 
2 
3 
4 
5 

Queue: 
1 
2 
3 
4 
5 

質問:

  1. はこの理にかなっていますか?バグですか?
  2. 少なくとも、キュー要素が正しい順序で返されることは保証できますか?
  3. StackまたはQueueを消費(処理)するときは、これを行うのが最善の方法ですか? &世論調査()の代わりに、ループのために)あなたは(ポップアップを使用する必要がwhile(!s.isEmpty()) { handle(s.pop()); }またはwhile(!l.isEmpty()) { handle(l.poll()); }
+0

通常のforループを使用してみましたか? –

答えて

14

興味深い脚注in Stack's Javadocあり:

LIFOスタック操作をより完全かつ一貫したセットが このクラスに優先して使用すべきであるのDequeインタフェースとその実装によって 提供されます。たとえば、次のようになります。

Deque stack = new ArrayDeque();

あなたのプログラムの拡張版:

public static void main(String[] args) { 
    Stack<Integer> s = new Stack<Integer>(); 
    Deque<Integer> d = new ArrayDeque<Integer>(); 
    Queue<Integer> l = new LinkedList<Integer>(); 

    for (int i : numbers) { 
     s.push(i); 
     l.offer(i); 
     d.push(i); 
    } 

    System.out.println("Stack: "); 
    for(Integer i : s) { 
     System.out.println(i); 
    } 

    System.out.println(); 
    System.out.println("Queue:"); 
    for(Integer i : l) { 
     System.out.println(i); 
    } 
    System.out.println(); 
    System.out.println("Deque:"); 
    for(Integer i : d) { 
     System.out.println(i); 
    } 
    } 

は、そのため、おそらくより一貫性のある動作のためのDequeに切り替え

.... 
Deque: 
5 
4 
3 
2 
1 

を与えます。

+0

これは他のものよりはるかに良い答えです。 +1 – durron597

14

:または私のようなものでより多くのマニュアルループを作る必要があります。 Stack/Queueによって提供されるAPIです。

繰り返しを実行すると、スタック/キューの内部表現が直接反復されます。

+0

おそらく、あなたがなぜpop()を使うことができないのかを知ることができます。たとえば、要素が削除された場合、他のコレクションではどうなりますか?そして、 '内部表現を反復する'というのは、(バインドされたサイズのキューはおそらく '循環型'なので)やや誤解を招く - イテレータは本当に何を返すのですか? –

関連する問題