Pila
Un Stack
es otra estructura de datos que opera bajo el principio Last In, First Out (LIFO). El mismo principio puede aplicarse a un Deque
, del que aprendiste antes, y los desarrolladores de Java recomiendan usar Deque
si hay necesidad de una estructura de datos que opera bajo el principio LIFO. La estructura de datos Stack
está obsoleta.
Deprecated
Cuando un elemento está marcado como obsoleto, significa que los autores de la biblioteca o lenguaje de programación aconsejan evitar su uso en código nuevo y recomiendan adoptar nuevos métodos, clases o enfoques que puedan proporcionar soluciones más seguras, eficientes o funcionales.
Un ejemplo es la clase Vector
de Java. Sus métodos han sido obsoletos en favor de colecciones más modernas como ArrayList
y LinkedList
. Si un programador todavía utiliza métodos Vector
, el compilador puede emitir una advertencia de que estos métodos están obsoletos.
Ejemplo en Java:
main.java
12345678910111213141516package com.example; import java.util.Vector; public class Main { public static void main(String[] args) { Vector<String> vector = new Vector<>(); // Adding an element (this method is deprecated) vector.addElement("Item"); // Compiler warning about the deprecated method // Note: 'addElement(java.lang.Object)' is deprecated. System.out.println(vector.get(0)); } }
Por lo tanto, no es recomendable utilizar una estructura de datos como Stack, pero hablaremos de ella en este capítulo porque es una estructura de datos interesante utilizada, por ejemplo, en el Java Memoria de pila.
Stack
Directo al grano, veamos los métodos de la clase Stack
:
Métodos
push(E elemento)
(adición): Añade un elemento al principio de la pila.
main.java
123456789101112package com.example; import java.util.Stack; public class Main { public static void main(String[] args) { Stack<String> stack = new Stack<>(); stack.push("One"); stack.push("Two"); System.out.println("Stack: " + stack); } }
La adición se realiza de la misma forma que en ArrayList
, así que veamos inmediatamente este método en combinación con el método pop()
:
pop()
: Elimina y devuelve el elemento de la parte superior de la pila.
main.java
1234567891011121314package com.example; import java.util.Stack; public class Main { public static void main(String[] args) { Stack<String> stack = new Stack<>(); stack.push("One"); stack.push("Two"); System.out.println("Stack: " + stack); stack.pop(); System.out.println("Stack after the `pop()` method: " + stack); } }
Este método elimina un elemento de la parte superior de la pila. Observe que el método pop()
elimina el último elemento añadido de la pila. Así es exactamente como funciona el principio LIFO.
También podemos ver qué elemento está en la parte superior de la pila:
- Mirar: Devuelve el elemento de la parte superior de la pila sin eliminarlo.
main.java
123456789101112131415package com.example; import java.util.Stack; public class Main { public static void main(String[] args) { Stack<String> stack = new Stack<>(); stack.push("One"); stack.push("Two"); System.out.println("Stack: " + stack); String top = stack.peek(); System.out.println("Top element of the stack: " + top); System.out.println("Stack after the `peek()` method: " + stack); } }
Con este método, miramos el elemento superior de la pila.
Uso
Consideremos un ejemplo de uso de la estructura de datos de la pila para navegar entre páginas en un navegador (esas flechas de avance y retroceso que usamos frecuentemente).
Vamos a planificar la implementación del historial del navegador e implementar métodos para dos botones (goBack()
y goForward()
).
Si no estás seguro de a qué botones me refiero, estoy hablando de estos botones:
Implementemos una clase que tenga métodos para operar estos dos botones usando la estructura de datos Stack
.
Cómo funcionará:
-
Tendremos dos pilas y una variable
String
. La primera pila almacenará los enlaces por los que navegamos al pulsar la flecha "back
". La segunda pila almacenará los enlaces por los que navegamos pulsando la flecha "adelante
". También tendremos una variableString
que almacena el enlace de la página actual. -
En esta clase, habrá cuatro métodos:
visitPage()
,goBack()
,goForward()
, ygetCurrentPage()
. Veámoslos paso a paso: -
El método
visitPage()
nos redirigirá a la URL especificada en el parámetro. Al pasar a una nueva página, el enlace anterior se añadirá a labackStack
. ElforwardStack
se borrará cuando nos movamos a una nueva página. Veamos la implementación en el código:
BrowserHistory.java
1234567891011121314151617181920212223242526import java.util.Stack; public class BrowserHistory { private Stack<String> backStack; private Stack<String> forwardStack; private String currentUrl; public BrowserHistory() { backStack = new Stack<>(); forwardStack = new Stack<>(); currentUrl = "https://codefinity.com/profile/my-home"; } public void visitPage(String url) { // When visiting a new page, add the current page to the "back" stack backStack.push(currentUrl); // Reset the "forward" stack as we moved to a new page forwardStack.clear(); // Set the current page to the new URL currentUrl = url; System.out.println("Visited page: " + url); } }
- De esta forma, podremos volver a la página anterior cuando naveguemos a una página nueva.
Vamos a implementar el método para volver. Funcionará así: añadimos el enlace actual a la
forwardStack
, luego eliminamos este enlace de labackStack
, y lo asignamos acurrentUrl
. Veamos la implementación en el código:
BrowserHistory.java
12345678910public void goBack() { if (!backStack.isEmpty()) { // Navigate to the previous page, move from the backStack to the forwardStack forwardStack.push(currentUrl); currentUrl = backStack.pop(); System.out.println("Went back to: " + currentUrl); } else { System.out.println("Cannot go back. Already at the beginning."); } }
-
Te recuerdo que el método
pop()
retira el elemento de la parte superior de la pila y lo devuelve. Por lo tanto, usando este método, inmediatamente asignamos el valor de la URL a la variablecurrentUrl
. También comprobamos que labackStack
no está vacía; de lo contrario, no podremos volver al enlace anterior (simplemente porque no estará allí). Si la pila está vacía, mostramos el mensaje correspondiente. -
De la misma manera, implementamos el método para navegar a la página siguiente. Simplemente intercambiamos los elementos de la pila:
BrowserHistory.java
12345678910public void goForward() { if (!forwardStack.isEmpty()) { // Navigate to the next page, move from the forwardStack to the backStack backStack.push(currentUrl); currentUrl = forwardStack.pop(); System.out.println("Went forward to: " + currentUrl); } else { System.out.println("Cannot go forward. Already at the latest page."); } }
- Ahora, todo lo que queda es implementar el método
getCurrentPage()
, que simplemente devolverá el valor decurrentUrl
.
Probando
A continuación, vamos a probar todo esto en el método main
. Usaremos el método visitPage()
tres veces para asegurarnos de que estos enlaces se guardan en el historial. Luego, usaremos el método goBack()
dos veces, seguido por el método goForward()
una vez, para verificar la funcionalidad de los métodos escritos.
Durante este proceso, seguiremos nuestro estado usando el método getCurrentPage()
. Puedes ejecutar el código de abajo y también intentar insertar más enlaces y utilizar diferentes métodos para probar la funcionalidad de esta clase:
Main.java
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778package com.example; import java.util.Stack; class Main { public static void main(String[] args) { BrowserHistory browser = new BrowserHistory(); System.out.println("Default page: " + browser.getCurrentPage()); browser.visitPage("https://codefinity.com/courses/tracks/7dfbcd35-5cde-49d3-80f1-bf1096487903"); browser.visitPage("https://codefinity.com/courses/v2/8204075c-f832-4cb9-88b1-4e24e74ebdcb/bb00e195-715e-477d-8927-964e6e27cf16/e66c57b4-5f36-43b2-bd3b-e1398044fcab"); browser.visitPage("https://codefinity.com/courses/v2/8204075c-f832-4cb9-88b1-4e24e74ebdcb/bb00e195-715e-477d-8927-964e6e27cf16/1585fb29-47cd-47a6-9fb3-5b391cad24e0"); System.out.println("Current Page after visiting 3 pages: " + browser.getCurrentPage()); browser.goBack(); browser.goBack(); System.out.println("Current Page after going back 2 times: " + browser.getCurrentPage()); browser.goForward(); System.out.println("Current Page after going forward: " + browser.getCurrentPage()); } } class BrowserHistory { private Stack<String> backStack; private Stack<String> forwardStack; private String currentUrl; public BrowserHistory() { backStack = new Stack<>(); forwardStack = new Stack<>(); currentUrl = "https://codefinity.com/profile/my-home"; } public void visitPage(String url) { // When visiting a new page, add the current page to the "back" stack backStack.push(currentUrl); // Reset the "forward" stack as we moved to a new page forwardStack.clear(); // Set the current page to the new URL currentUrl = url; System.out.println("Visited page: " + url); } public void goBack() { if (!backStack.isEmpty()) { // Navigate to the previous page, move from the backStack to the forwardStack forwardStack.push(currentUrl); currentUrl = backStack.pop(); System.out.println("Went back to: " + currentUrl); } else { System.out.println("Cannot go back. Already at the beginning."); } } public void goForward() { if (!forwardStack.isEmpty()) { // Navigate to the next page, move from the forwardStack to the backStack backStack.push(currentUrl); currentUrl = forwardStack.pop(); System.out.println("Went forward to: " + currentUrl); } else { System.out.println("Cannot go forward. Already at the latest page."); } } public String getCurrentPage() { return currentUrl; } }
Nota
Si el gran número de salidas por consola es molestoso, puedes eliminar las operaciones de impresión por consola de los métodos, dejando sólo salidas intermedias por pantalla.
Recuerda que la clase Stack
está deprecada, y es mejor usar Deque
en su lugar. En este ejemplo, Stack
se implementa basándose en el principio LIFO, y también podemos implementar Deque
ya que es una cola de doble extremo que puede operar basándose tanto en el principio FIFO como en el LIFO.
Si tienes dificultades para entender el ejemplo o el código en general, no dudes en hacer clic en "¿No está claro?" y hacer tu pregunta. Haré todo lo que esté en mi mano para ayudarte a entender el material lo antes posible.
Además, no olvides que puedes aprovechar la función "Chatea con la comunidad", ¡donde usuarios como tú están dispuestos a ayudarte!
1. ¿Cuál es el principio básico de una estructura de datos Stack
?
2. ¿Qué interfaz Java implementa la clase Stack
?
3. ¿Cuál es el método utilizado para añadir un elemento a la parte superior de la pila en Java?
4. ¿Cuál de las siguientes colecciones de Java se considera una alternativa más moderna a Stack
?
5. En Java, ¿qué devolverá el método pop()
de una Pila
?
¡Gracias por tus comentarios!
Pregunte a AI
Pregunte a AI
Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla
Awesome!
Completion rate improved to 4
Pila
Desliza para mostrar el menú
Un Stack
es otra estructura de datos que opera bajo el principio Last In, First Out (LIFO). El mismo principio puede aplicarse a un Deque
, del que aprendiste antes, y los desarrolladores de Java recomiendan usar Deque
si hay necesidad de una estructura de datos que opera bajo el principio LIFO. La estructura de datos Stack
está obsoleta.
Deprecated
Cuando un elemento está marcado como obsoleto, significa que los autores de la biblioteca o lenguaje de programación aconsejan evitar su uso en código nuevo y recomiendan adoptar nuevos métodos, clases o enfoques que puedan proporcionar soluciones más seguras, eficientes o funcionales.
Un ejemplo es la clase Vector
de Java. Sus métodos han sido obsoletos en favor de colecciones más modernas como ArrayList
y LinkedList
. Si un programador todavía utiliza métodos Vector
, el compilador puede emitir una advertencia de que estos métodos están obsoletos.
Ejemplo en Java:
main.java
12345678910111213141516package com.example; import java.util.Vector; public class Main { public static void main(String[] args) { Vector<String> vector = new Vector<>(); // Adding an element (this method is deprecated) vector.addElement("Item"); // Compiler warning about the deprecated method // Note: 'addElement(java.lang.Object)' is deprecated. System.out.println(vector.get(0)); } }
Por lo tanto, no es recomendable utilizar una estructura de datos como Stack, pero hablaremos de ella en este capítulo porque es una estructura de datos interesante utilizada, por ejemplo, en el Java Memoria de pila.
Stack
Directo al grano, veamos los métodos de la clase Stack
:
Métodos
push(E elemento)
(adición): Añade un elemento al principio de la pila.
main.java
123456789101112package com.example; import java.util.Stack; public class Main { public static void main(String[] args) { Stack<String> stack = new Stack<>(); stack.push("One"); stack.push("Two"); System.out.println("Stack: " + stack); } }
La adición se realiza de la misma forma que en ArrayList
, así que veamos inmediatamente este método en combinación con el método pop()
:
pop()
: Elimina y devuelve el elemento de la parte superior de la pila.
main.java
1234567891011121314package com.example; import java.util.Stack; public class Main { public static void main(String[] args) { Stack<String> stack = new Stack<>(); stack.push("One"); stack.push("Two"); System.out.println("Stack: " + stack); stack.pop(); System.out.println("Stack after the `pop()` method: " + stack); } }
Este método elimina un elemento de la parte superior de la pila. Observe que el método pop()
elimina el último elemento añadido de la pila. Así es exactamente como funciona el principio LIFO.
También podemos ver qué elemento está en la parte superior de la pila:
- Mirar: Devuelve el elemento de la parte superior de la pila sin eliminarlo.
main.java
123456789101112131415package com.example; import java.util.Stack; public class Main { public static void main(String[] args) { Stack<String> stack = new Stack<>(); stack.push("One"); stack.push("Two"); System.out.println("Stack: " + stack); String top = stack.peek(); System.out.println("Top element of the stack: " + top); System.out.println("Stack after the `peek()` method: " + stack); } }
Con este método, miramos el elemento superior de la pila.
Uso
Consideremos un ejemplo de uso de la estructura de datos de la pila para navegar entre páginas en un navegador (esas flechas de avance y retroceso que usamos frecuentemente).
Vamos a planificar la implementación del historial del navegador e implementar métodos para dos botones (goBack()
y goForward()
).
Si no estás seguro de a qué botones me refiero, estoy hablando de estos botones:
Implementemos una clase que tenga métodos para operar estos dos botones usando la estructura de datos Stack
.
Cómo funcionará:
-
Tendremos dos pilas y una variable
String
. La primera pila almacenará los enlaces por los que navegamos al pulsar la flecha "back
". La segunda pila almacenará los enlaces por los que navegamos pulsando la flecha "adelante
". También tendremos una variableString
que almacena el enlace de la página actual. -
En esta clase, habrá cuatro métodos:
visitPage()
,goBack()
,goForward()
, ygetCurrentPage()
. Veámoslos paso a paso: -
El método
visitPage()
nos redirigirá a la URL especificada en el parámetro. Al pasar a una nueva página, el enlace anterior se añadirá a labackStack
. ElforwardStack
se borrará cuando nos movamos a una nueva página. Veamos la implementación en el código:
BrowserHistory.java
1234567891011121314151617181920212223242526import java.util.Stack; public class BrowserHistory { private Stack<String> backStack; private Stack<String> forwardStack; private String currentUrl; public BrowserHistory() { backStack = new Stack<>(); forwardStack = new Stack<>(); currentUrl = "https://codefinity.com/profile/my-home"; } public void visitPage(String url) { // When visiting a new page, add the current page to the "back" stack backStack.push(currentUrl); // Reset the "forward" stack as we moved to a new page forwardStack.clear(); // Set the current page to the new URL currentUrl = url; System.out.println("Visited page: " + url); } }
- De esta forma, podremos volver a la página anterior cuando naveguemos a una página nueva.
Vamos a implementar el método para volver. Funcionará así: añadimos el enlace actual a la
forwardStack
, luego eliminamos este enlace de labackStack
, y lo asignamos acurrentUrl
. Veamos la implementación en el código:
BrowserHistory.java
12345678910public void goBack() { if (!backStack.isEmpty()) { // Navigate to the previous page, move from the backStack to the forwardStack forwardStack.push(currentUrl); currentUrl = backStack.pop(); System.out.println("Went back to: " + currentUrl); } else { System.out.println("Cannot go back. Already at the beginning."); } }
-
Te recuerdo que el método
pop()
retira el elemento de la parte superior de la pila y lo devuelve. Por lo tanto, usando este método, inmediatamente asignamos el valor de la URL a la variablecurrentUrl
. También comprobamos que labackStack
no está vacía; de lo contrario, no podremos volver al enlace anterior (simplemente porque no estará allí). Si la pila está vacía, mostramos el mensaje correspondiente. -
De la misma manera, implementamos el método para navegar a la página siguiente. Simplemente intercambiamos los elementos de la pila:
BrowserHistory.java
12345678910public void goForward() { if (!forwardStack.isEmpty()) { // Navigate to the next page, move from the forwardStack to the backStack backStack.push(currentUrl); currentUrl = forwardStack.pop(); System.out.println("Went forward to: " + currentUrl); } else { System.out.println("Cannot go forward. Already at the latest page."); } }
- Ahora, todo lo que queda es implementar el método
getCurrentPage()
, que simplemente devolverá el valor decurrentUrl
.
Probando
A continuación, vamos a probar todo esto en el método main
. Usaremos el método visitPage()
tres veces para asegurarnos de que estos enlaces se guardan en el historial. Luego, usaremos el método goBack()
dos veces, seguido por el método goForward()
una vez, para verificar la funcionalidad de los métodos escritos.
Durante este proceso, seguiremos nuestro estado usando el método getCurrentPage()
. Puedes ejecutar el código de abajo y también intentar insertar más enlaces y utilizar diferentes métodos para probar la funcionalidad de esta clase:
Main.java
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778package com.example; import java.util.Stack; class Main { public static void main(String[] args) { BrowserHistory browser = new BrowserHistory(); System.out.println("Default page: " + browser.getCurrentPage()); browser.visitPage("https://codefinity.com/courses/tracks/7dfbcd35-5cde-49d3-80f1-bf1096487903"); browser.visitPage("https://codefinity.com/courses/v2/8204075c-f832-4cb9-88b1-4e24e74ebdcb/bb00e195-715e-477d-8927-964e6e27cf16/e66c57b4-5f36-43b2-bd3b-e1398044fcab"); browser.visitPage("https://codefinity.com/courses/v2/8204075c-f832-4cb9-88b1-4e24e74ebdcb/bb00e195-715e-477d-8927-964e6e27cf16/1585fb29-47cd-47a6-9fb3-5b391cad24e0"); System.out.println("Current Page after visiting 3 pages: " + browser.getCurrentPage()); browser.goBack(); browser.goBack(); System.out.println("Current Page after going back 2 times: " + browser.getCurrentPage()); browser.goForward(); System.out.println("Current Page after going forward: " + browser.getCurrentPage()); } } class BrowserHistory { private Stack<String> backStack; private Stack<String> forwardStack; private String currentUrl; public BrowserHistory() { backStack = new Stack<>(); forwardStack = new Stack<>(); currentUrl = "https://codefinity.com/profile/my-home"; } public void visitPage(String url) { // When visiting a new page, add the current page to the "back" stack backStack.push(currentUrl); // Reset the "forward" stack as we moved to a new page forwardStack.clear(); // Set the current page to the new URL currentUrl = url; System.out.println("Visited page: " + url); } public void goBack() { if (!backStack.isEmpty()) { // Navigate to the previous page, move from the backStack to the forwardStack forwardStack.push(currentUrl); currentUrl = backStack.pop(); System.out.println("Went back to: " + currentUrl); } else { System.out.println("Cannot go back. Already at the beginning."); } } public void goForward() { if (!forwardStack.isEmpty()) { // Navigate to the next page, move from the forwardStack to the backStack backStack.push(currentUrl); currentUrl = forwardStack.pop(); System.out.println("Went forward to: " + currentUrl); } else { System.out.println("Cannot go forward. Already at the latest page."); } } public String getCurrentPage() { return currentUrl; } }
Nota
Si el gran número de salidas por consola es molestoso, puedes eliminar las operaciones de impresión por consola de los métodos, dejando sólo salidas intermedias por pantalla.
Recuerda que la clase Stack
está deprecada, y es mejor usar Deque
en su lugar. En este ejemplo, Stack
se implementa basándose en el principio LIFO, y también podemos implementar Deque
ya que es una cola de doble extremo que puede operar basándose tanto en el principio FIFO como en el LIFO.
Si tienes dificultades para entender el ejemplo o el código en general, no dudes en hacer clic en "¿No está claro?" y hacer tu pregunta. Haré todo lo que esté en mi mano para ayudarte a entender el material lo antes posible.
Además, no olvides que puedes aprovechar la función "Chatea con la comunidad", ¡donde usuarios como tú están dispuestos a ayudarte!
1. ¿Cuál es el principio básico de una estructura de datos Stack
?
2. ¿Qué interfaz Java implementa la clase Stack
?
3. ¿Cuál es el método utilizado para añadir un elemento a la parte superior de la pila en Java?
4. ¿Cuál de las siguientes colecciones de Java se considera una alternativa más moderna a Stack
?
5. En Java, ¿qué devolverá el método pop()
de una Pila
?
¡Gracias por tus comentarios!