Exemplo de Lista Duplamente Encadeada com nó cabeça

Para aqueles que, da mesma forma que eu, estão quebrando cabeça com Listas Duplamente Encadeadas com nó cabeça, aí vai um exemplo não orientado.
Perdoem-me os mais experientes pelos erros de construção.
Mas, da mesma forma que estou tentando ajudar alguém, se os mais experientes puderem implementar as outras opções do menu eu agradeço.


import javax.swing.JOptionPane;

/**
 * * @author robson.alcantara
 */
public class LDupEncadeadaComNoCabecaExercicio {

    static final String[] menuInicial = {
        "Inserir no Início da Lista",
        "Inserir no Final da Lista",
        "Inserir Após um valor",
        "Remover do Início da Lista",
        "Remover do Final da Lista",
        "Remover Após um valor",
        "Limpar a Lista",
        "Listar",
        "Sair"
    };

    public static void main(String[] args) {

        Classe_ListaDencadeada<String> auxiliar;
        Classe_ListaDencadeada kbeca = null;
        String entrada, depois, opcao;

        do {
            opcao = (String) (JOptionPane.showInputDialog(null, "Escolha sua opção", "Painel de opções", JOptionPane.QUESTION_MESSAGE, null, menuInicial, menuInicial[0]));

            switch (opcao) {
                case "Inserir no Início da Lista":
                    entrada = (JOptionPane.showInputDialog(null, "Informe o elemento a ser inserido no início da lista"));
                    if (kbeca == null) {
                        Classe_ListaDencadeada<String> novo;
                        novo = new Classe_ListaDencadeada<>(entrada);
                        kbeca = novo;
                        kbeca.setAnterior(kbeca);
                        Classe_ListaDencadeada.aumentaTamanho();
                    } else {
                        Classe_ListaDencadeada<String> novo = new Classe_ListaDencadeada<>(entrada, null, kbeca);
                        novo.setAnterior(kbeca.getAnterior());
                        kbeca.setAnterior(novo);
                        kbeca = novo;
                        Classe_ListaDencadeada.aumentaTamanho();
                    }
                    break;
                case "Inserir no Final da Lista":
                    entrada = (JOptionPane.showInputDialog(null, "Informe o elemento a ser inserido no fim da lista"));
                    if (kbeca == null) {
                        Classe_ListaDencadeada<String> novo;
                        novo = new Classe_ListaDencadeada<>(entrada);
                        kbeca = novo;
                        kbeca.setAnterior(kbeca);
                        Classe_ListaDencadeada.aumentaTamanho();
                    } else {
                        Classe_ListaDencadeada<String> novo = new Classe_ListaDencadeada<>(entrada);
                        novo.setAnterior(kbeca.getAnterior());
                        kbeca.getAnterior().setProximo(novo);
                        kbeca.setAnterior(novo);
                        Classe_ListaDencadeada.aumentaTamanho();
                    }
                    break;
                case "Inserir Após um valor":
                    entrada = (JOptionPane.showInputDialog(null, "Informe o elemento a ser inserido"));
                    depois = (JOptionPane.showInputDialog(null, "Ele será inserido após qual elemento?"));
                    auxiliar = kbeca;
                    if (kbeca != null) {
                        while (auxiliar.getObjeto() != null) {
                            if (auxiliar.getObjeto().equals(depois)) {
                                Classe_ListaDencadeada<String> novo = new Classe_ListaDencadeada<>(entrada);
                                novo.setAnterior(auxiliar);
                                novo.setProximo(auxiliar.getProximo());
                                auxiliar.setProximo(novo);
                                auxiliar.getProximo().setAnterior(novo);
                                Classe_ListaDencadeada.aumentaTamanho();
                                break;
                            } else {
                                auxiliar = auxiliar.getProximo();
                            }
                        }
                    }
                    break;
                case "Remover do Início da Lista":
                    break;
                case "Remover do Final da Lista":
                    break;
                case "Limpar a Lista":
                    break;
                case "Listar":
                    StringBuilder saida = new StringBuilder();
                    int busca = Classe_ListaDencadeada.getTamanho();
                    auxiliar = kbeca;
                    while (busca != 0) {
                        saida.append(auxiliar.getObjeto().toString());
                        auxiliar = auxiliar.getProximo();
                        busca--;
                    }
                    JOptionPane.showMessageDialog(null, saida.toString());
                    break;
            }
        } while (!"Sair".equals(opcao));

    }
}

E, a classe que define o tipo:


/**
 * @author robson.alcantara
 */
public class Classe_ListaDencadeada<E> {

    private static int tamanho;
    private E objeto;
    private Classe_ListaDencadeada<E> proximo;
    private Classe_ListaDencadeada<E> anterior;

    /**
     * Este construtor cria um nó que recebe como valor o objeto passado como
     * parâmetro. Ele, automaticamente, apontará para anterior nulo e para
     * próximo nulo.
     *
     * @param objeto
     */
    public Classe_ListaDencadeada(E objeto) {
        this.objeto = objeto;
        this.anterior = null;
        this.proximo = null;
    }

    /**
     * Este construtor cria um nó e o aloca entre os nós passados como
     * parâmetros. Ele automaticamente apontará para os nós.
     *
     * @param objeto
     * @param anterior
     * @param proximo
     */
    public Classe_ListaDencadeada(E objeto, Classe_ListaDencadeada<E> anterior, Classe_ListaDencadeada<E> proximo) {
        this.objeto = objeto;
        this.proximo = proximo;
        this.anterior = anterior;
    }

    public static int getTamanho() {
        return tamanho;
    }

    public static void aumentaTamanho() {
        tamanho++;
    }
    public static void diminuiTamanho() {
        tamanho--;
    }

    public E getObjeto() {
        return objeto;
    }

    public Classe_ListaDencadeada<E> getProximo() {
        return proximo;
    }

    public void setProximo(Classe_ListaDencadeada<E> proximo) {
        this.proximo = proximo;
    }

    public Classe_ListaDencadeada<E> getAnterior() {
        return anterior;
    }

    public void setAnterior(Classe_ListaDencadeada<E> anterior) {
        this.anterior = anterior;
    }
}

Observem que eu utilizei Generics.
E, ainda, implementei dois construtores diferentes. Vejam no próprio JavaDoc dos construtores.

Boa noite. Aguardo comentários construtivos.
Abraço á equipe GUJ.
:smiley:

AH! Sim! Obrigado ao GUJ por sanar tantas dúvidas minhas (que ainda estou iniciando os estudos).
Faço BSI em Sergipe.