Las pilas en Java junto con las listas constituyen una estructura básica de datos puesto que hay muchos comportamientos que obedecen al apilamiento de ítems.

Visite la sección de listas para encontrar detalles de estas estructuras de datos.

1. ¿Qué es una pila?

Una pila es una estructura de datos enlazada que sigue una disciplina LIFO (Last In, First Out – Último en entrar, Primero en salir) en la cual el ultimo elemento que entra es el primero en ser retirado, adicionalmente la estructura, aunque continua siendo una estructura lineal no se puede manipular cualquier elemento como sucedía con las listas, en las pilas solamente se puede acceder al elemento que esta en la cima, de manera que si se quiere alcanzar el elemento de la base, primero se requerirá desapilar todos los elementos. La siguiente figura muestra gráficamente una pila.

Pila enlazada
Figura 1. Pilas

Las pilas tienen muchos usos en informática, un ejemplo sencillo consiste en la pila de llamados al sistema, en la cual se apilan y desapilan los llamados a los métodos a medida que se invocan los métodos o se retorna de ellos, respectivamente.2. Implementación de una pila

La implementación de una pila enlazada utiliza la misma clase Node que se utilizó en las listas enlazadas, la diferencia radica que en los métodos que se utilizan para manipular la pila y que se resumen a continuación:

  • push: este método se encarga de agregar un nuevo elemento a la cima de la pila.
  • pop: este método remueve el elemento de la cima y lo retorna.
  • peek: este método se encarga de retornar el elemento de la cima sin eliminarlo de la pila.

1.1. Interface de las Pilas

A continuación se muestra el código correspondiente a las operaciones de una pila con su respectiva documentación.

package stacks;
/**
 * Provee las acciones que se pueden realizar con una pila
 * @author ochoscar
 * @param< T > Tipo genérico de los cuales se almacenaran elementos dentro de la pila
 */
public interface IStack< T > {
    /**
     * Método que verifica si la pila esta vacía
     * @return Devuelve true si la pila esta
     * vacía y false en caso contrario
     */
    public boolean isEmpty();
    /**
     * Método que determina el tamaño de la pila
     * @return Devuelve un entero que indica el tamaño de la pila
     */
    public int size();
    /**
     * Agrega un elemento en la cima de la pila
     * @param item Item de tipo genérico a ser agregado a la pila
     * @return Devuelve la misma pila que llamo al método
     */
    public IStack push(T item);
    /**
     * Remueve un elemento de la cima de la pila y lo devuelve para su manipulación
     * @return El elemento que se encontraba en la cima de pila
     */
    public T pop();
    /**
     * Devuelve un elemento de la cima de la pila sin removerlo
     * @return El elemento que se encontraba en la cima de pila
     */
    public T peek();
}

1.2. Clase Pila en Java

La implementación de la interface anterior se encuentra e n el siguiente código. Observe que solamente es necesario referenciar al elemento top o de la cima de la pila para realizar todas las operaciones. Algo importante también es que las operaciones de la pila no requieren de ciclos, por lo tanto la estructura se vuelve supremamente eficiente y así mismo no aporta mayor valor realizar una Pila con arreglos, aunque es perfectamente posible.

package stacks;
/**
 * Clase que encapsula las diferentes acciones de una pila enlazada
 * @author ochoscar
 * @param< T > Tipo genérico que contra los item de la pila
 */
public class Stack< T > implements IStack< T > {
    ////////////////////
    // Atributos
    ////////////////////
    /** Referencia a la cima de la pila */
    private Node< T > top;
    /** Tamaño de la cola */
    private int stackSize = 0;
    ////////////////////
    // Métodos
    ////////////////////
    /**
     * Método que verifica si la pila esta vacia
     * @return Devuelve true si la pila esta
     * vacía y false en caso contrario
     */
    @Override
    public boolean isEmpty() {
        return stackSize == 0;
    }
    /**
     * Método que determina el tamaño de la pila
     * @return Devuelve un entero que indica el tamaño de la pila
     */
    @Override
    public int size() {
        return stackSize;
    }
    /**
     * Agrega un elemento en la cima de la pila
     * @param item Item de tipo genérico a ser agregado a la pila
     * @return Devuelve la misma pila que llamo al método
     */
    @Override
    public IStack push(T item) {
        top = new Node<>(item, top);
        stackSize++;
        return this;
    }
    /**
     * Remueve un elemento de la cima de la pila y lo devuelve para su manipulación
     * @return El elemento que se encontraba en la cima de pila
     */
    @Override
    public T pop() {
        if(stackSize == 0) return null;
        T item = top.getItem();
        top = top.getNext();
        stackSize--;
        return item;
    }
    /**
     * Devuelve un elemento de la cima de la pila sin removerlo
     * @return El elemento que se encontraba en la cima de pila
     */
    @Override
    public T peek() {
        return top != null ? top.getItem() : null;
    }
}

2. Artículos de Interés