Por que eu devo ler este artigo: Este artigo é útil por apresentar como utilizar classes genéricas, ou classes parametrizadas, para codificar uma estrutura de dados, de maneira que o compilador consiga realizar a checagem dos tipos que nela forem armazenados. Além disso, algumas características mais avançadas das classes genéricas, como as que fazem uso de conceitos como o relacionamento de herança entre classes, serão explicadas e demonstradas, de forma que, em um processo incremental, problemas como a inclusão inadvertida de elementos de tipos distintos na estrutura de dados; uso de hierarquias de classes para definir um conjunto de diferentes tipos de elementos que podem ser manipulados na estrutura; e também a especificação de um comportamento padronizado para os dados armazenados serão expostos e as suas soluções discutidas com base nos diferentes exemplos de código para cada uma destas situações. A partir desse conteúdo o leitor será capaz de desenvolver um código mais seguro e flexível, requisitos fundamentais para alcançar um código de qualidade.

No artigo “Programando com estruturas de dados e padrões de projeto”, publicado na Easy Java Magazine número 49, a estrutura de dados que utiliza uma sequência de nós auto ligados, conhecida como lista encadeada, foi descrita. No mesmo texto apresentou-se também o padrão Iterator, que permite a navegação, ou iteração, pela lista sem que seja necessário conhecer ou ter acesso aos detalhes da sua implementação, que pode ser, como no exemplo, por encadeamentos duplos, por encadeamentos simples ou mesmo utilizando vetores.

As listas são estruturas de dados muito flexíveis, permitindo que novos elementos sejam incluídos em qualquer posição, e também que sejam removidos de qualquer posição. Estas características já foram explicadas e demonstradas anteriormente, e o foco agora é em como melhorar a usabilidade da classe que as implementa.

Uma situação que pode ocorrer ao utilizar uma estrutura de dados como a que foi definia, e cuja estrutura está resumida na Listagem 1, é a inclusão, por acidente, de mais de um tipo de dado na mesma lista. Uma situação como esta é possível porque no código, para que seja viável armazenar referências a quaisquer objetos, os dados foram declarados como sendo do tipo Object. Como em Java todas as classes são estendidas direta ou indiretamente da classe Object, é possível referenciar qualquer objeto como sendo deste tipo, o que permite, também, que a classe de lista funcione adequadamente sem que seja necessário alterar seu código para cada tipo com o qual se desejar trabalhar. Isto porque a lista não necessita saber qual é o tipo que está armazenando, mas apenas de uma referência ao objeto para que possa responder às consultas realizadas.


public class ListaDupEncadeada {
 // A classe que representa os nós da lista utiliza a classe Object 
 para definir a referência ao dado associado à posição da lista que este nó representa.
 private class No{
       // Referência ao próximo elemento da lista
       No proximo;
       // Referência ao elemento anterior na lista
       No anterior;
       // Referência ao dado armazenado no nó atual da lista
       Object dado;

       // Constrói um nó para armazenar um objeto na lista
       No(Object obj) { ... }
       // Constrói um nó para armazenar um objeto na lista, indicando quais os
       // nós anterior e próximo
       No(Object obj, No prox, No ant) { ... }
 }
 // Implementação da interface Iterator, que define os métodos de navegação na lista
 private class IteratorLista implements Iterator {
       // Referência ao nó apontado pelo iterador da lista durante a navegação
       No noAtual;

       // Retorna o dado associado ao nó atual. Caso o iterador não seja válido
       // (noAtual é nulo), retorna um objeto nulo
       public Object dado() { ... }
       // Coloca o iterador no próximo elemento da lista e retorna o dado
       // associado ao nó atual. Caso o iterador não seja válido (noAtual é
       // nulo), retorna um objeto nulo
       public Object proximo() { ... }
       // Coloca o iterador no elemento anterior da lista e retorna o dado
       // associado ao nó atual. Caso o iterador não seja válido (noAtual é
       // nulo), retorna um objeto nulo
       public Object anterior() { . ... 

Fim do trecho gratuito • continue abaixo
CONTEÚDO EXCLUSIVO

Desbloqueie toda a DevMedia

  • +2000 artigos e vídeos
  • +40 trilhas sobre Front-end, Back-end, IA e muito mais
  • +5000 exercícios práticos
  • Mentorias ao vivo individuais
até 50% OFF
A partir de
R$ 69 /mês
Assinar agora