example - stack java 8
¿Hay algún error en el iterador de java.util.Stack? (6)
Bueno, por principio, no debe iterar sobre una Stack
, sino solo presionar hacia arriba o hacia arriba desde arriba. En cuanto a la implementación real, la mayoría de los lenguajes, incluido Java, usan otro collection type
para implementar una Stack
. Desde el punto de vista estricto de los requisitos, debería permitir el uso constante del tiempo push, top and pop
.
Cualquier característica adicional (o error en este caso), simplemente debe ignorarse y no dependerse de la codificación.
Hoy traté de empujar en la clase java.util.Stack
y luego usar el Iterator
para iterar (sin usar pop) a través de los elementos. Esperaba propiedad de LIFO pero me sorprendió.
Aquí está el código que estaba intentando.
import java.util.*;
import java.util.Stack;
public class Main {
public static void main(String[] args) {
RobStack<Integer> rstack = new RobStack<Integer>(); // Correct Implementation
Stack<Integer> jstack = new Stack<Integer>(); // Default Java Implementation
rstack.push(0); jstack.push(0);
rstack.push(1); jstack.push(1);
rstack.push(2); jstack.push(2);
rstack.push(3); jstack.push(3);
System.out.print("Algo Stack: ");
for (int i : rstack)
System.out.print(i + " ");
System.out.print("/nJava Stack: ");
for (int i : jstack)
System.out.print(i + " ");
}
}
El resultado del programa anterior se da a continuación:
Algo Stack: 3 2 1 0
Java Stack: 0 1 2 3
En el código anterior, jstack
usa la implementación Java predeterminada y rstack
usa la implementación proporcionada por Robert Sedgewick para su clase Algorithm. Descubrí que la implementación del Prof. Robert funciona bien pero falla la implementación de java.util.Stack
.
¿Es un error o es por diseño ?
Consulte el error ID 4475301: RFE: java.util.Stack.iterator () itera de manera incorrecta . Este comportamiento es por (mal) diseño. Stack
métodos de iteración de Stack
incorporados de Java se heredan de otras clases, por lo que no se comportan como cabría esperar.
Deberías usar Deque en lugar de Stack.
Deque<Integer> stack = new ArrayDeque<Integer>();
Stack hereda .listIterator () de AbstractList que permite la iteración de orden inversa.
Stack<Integer> stack = new Stack<Integer>();
stack.push(1);
stack.push(2);
stack.push(3);
for (ListIterator<Integer> iterator = stack.listIterator(stack.size()); iterator.hasPrevious();) {
Integer integer = iterator.previous();
System.out.println(integer);
}
// Output: 3 2 1
Tal vez, puede usar .get () para imprimir elementos dentro de la pila de arriba a abajo.
Stack<Integer> stack = new Stack<Integer>();
stack.push(3);
stack.push(2);
stack.push(1);
// print from top to bottom
for(int i = stack.size() - 1; i >= 0; i--){
System.out.println(stack.get(i));
}
/*
output
1
2
3
*/
Las colecciones de Eclipse incluyen una implementación de pila mutable en la que el iterador devuelve valores de arriba a abajo. Este código imprime 3, 2, luego 1.
MutableStack<Integer> stack = ArrayStack.newStack();
stack.push(1);
stack.push(2);
stack.push(3);
for (Iterator<Integer> iterator = stack.iterator(); iterator.hasNext(); )
{
Integer each = iterator.next();
System.out.println(each);
}
MutableStack
no extiende MutableCollection
o Collection
, por lo que no puede eliminar desde el medio de la pila, por ejemplo. Los métodos que implementan patrones de iteración internos como forEach()
, select()
, collect()
, anySatisfy()
, allSatisfy()
, etc. también procesan elementos de arriba a abajo. Este código imprime lo mismo.
stack.forEach(Procedures.println(System.out));
Nota: soy un committer para colecciones de Eclipse.