java 堆栈,foreach,错误的顺序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14900710/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 17:47:00  来源:igfitidea点击:

Stack, foreach, wrong order?

javastackqueue

提问by durron597

When using Java's foreach syntax, Stackdoesn't use LIFO ordering on the outputted elements. Consider the following code:

使用 Java 的foreach 语法时,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);
    }
  }
}

Output:

输出:

Stack: 
1
2
3
4
5

Queue:
1
2
3
4
5

Questions:

问题:

  1. Does this make sense? Is it a bug?
  2. Can I guarantee that this will, at least, return Queue elements in the correct order?
  3. When consuming (processing) a Stackor a Queue, is this the best way to do it? Or should I make a more manual loop with something like: while(!s.isEmpty()) { handle(s.pop()); }or while(!l.isEmpty()) { handle(l.poll()); }
  1. 这有意义吗?这是一个错误吗?
  2. 我可以保证这至少会以正确的顺序返回 Queue 元素吗?
  3. 使用(处理) aStack或 a 时Queue,这是最好的方法吗?或者我应该使用以下内容进行更手动的循环:while(!s.isEmpty()) { handle(s.pop()); }while(!l.isEmpty()) { handle(l.poll()); }

采纳答案by fvu

There is an interesting footnote in Stack's Javadoc:

Stack 的 Javadoc 中有一个有趣的脚注:

A more complete and consistent set of LIFO stack operations is provided by the Deque interface and its implementations, which should be used in preference to this class. For example:

Deque stack = new ArrayDeque();

Deque 接口及其实现提供了一组更完整和一致的 LIFO 堆栈操作,应优先使用此类。例如:

Deque stack = new ArrayDeque();

An extended version of your program:

程序的扩展版本:

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

gives

....
Deque:
5
4
3
2
1

So maybe switch to Deque for a more consistent behavior.

所以也许切换到 Deque 以获得更一致的行为。

回答by Amit

You need to use pop() & poll() instead of for loop. Thats the API offered by Stack/Queue.

您需要使用 pop() 和 poll() 而不是 for 循环。这就是 Stack/Queue 提供的 API。

When you iterate, you are directly iterating the internal representation of Stack/Queue.

当你迭代的时候,你是在直接迭代 Stack/Queue 的内部表示。