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.