2013-02-15 21 views
17

Podczas korzystania z Javy for dla każdej składni, Stack nie stosuje się porządkowania LIFO na wyjściowych elementach. Rozważmy następujący kod:Stos, foreach, zła kolejność?

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); 
    } 
    } 
} 

wyjścia:

Stack: 
1 
2 
3 
4 
5 

Queue: 
1 
2 
3 
4 
5 

pytania:

  1. Czy to ma sens? Czy to błąd?
  2. Czy mogę zagwarantować, że to przynajmniej zwróci elementy kolejki we właściwej kolejności?
  3. Podczas korzystania (przetwarzania) z Stack lub , jest to najlepszy sposób to zrobić? Czy powinienem uczynić bardziej ręcznego pętli z czymś takim: while(!s.isEmpty()) { handle(s.pop()); } lub while(!l.isEmpty()) { handle(l.poll()); }
+0

Czy próbowałeś używać zwykłej pętli for? –

Odpowiedz

14

Jest ciekawy przypis in Stack's Javadoc:

bardziej kompletny i spójny zestaw działań stosu LIFO jest dostarczane przez interfejs deque i jej implementacji, które powinny pierwszeństwo do tej klasy. Na przykład:

Deque stack = new ArrayDeque();

rozszerzona wersja programu:

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); 
    } 
    } 

daje

.... 
Deque: 
5 
4 
3 
2 
1 

Więc może przełączyć się deque bardziej konsekwentne zachowanie.

+0

To o wiele lepsza odpowiedź niż druga. +1 – durron597

14

Trzeba użyć pop() & poll() zamiast do pętli. Jest to API oferowane przez Stack/Queue.

Podczas wykonywania iteracji następuje bezpośrednia iteracja wewnętrznej reprezentacji stosu/kolejki.

+0

Być może powinieneś pójść w kierunku, dlaczego 'why_' pop() 'nie może być użyty. Na przykład, co dzieje się w innych kolekcjach, jeśli element zostanie usunięty? I "iterowanie reprezentacji wewnętrznej" jest nieco mylące (ponieważ kolejka o ograniczonych rozmiarach jest prawdopodobnie "okrągła") - co tak naprawdę powraca iterator? –