Stack, foreach, неправильный порядок?

При использовании Java for каждого синтаксиса Stack не использует LIFO-упорядочение на выводимых элементах. Рассмотрим следующий код:

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

Вопросы:

  • Это имеет смысл? Это ошибка?
  • Могу ли я гарантировать, что это, по крайней мере, вернет элементы очереди в правильном порядке?
  • При потреблении (обработке) a Stack или Queue, это лучший способ сделать это? Или я должен сделать более ручную петлю с чем-то вроде: while(!s.isEmpty()) { handle(s.pop()); } или while(!l.isEmpty()) { handle(l.poll()); }

Ответы

Ответ 1

Есть интересная сноска в Stack 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:
5
4
3
2
1

Так что, возможно, переключитесь на Deque для более последовательного поведения.

Ответ 2

Вам нужно использовать pop() и poll() вместо цикла. Это API, предлагаемый Stack/Queue.

Когда вы выполняете итерацию, вы выполняете прямое внутреннее представление Stack/Queue.