Por que eu devo ler este artigo:Na linguagem Java existem diversos objetos que servem como containers de outros objetos, prontos para serem utilizados, facilitando a manipulação e a passagem de informação entre métodos e aplicações.

Estes containers, ou coleções de objetos, possuem funcionalidades que nos permitem executar as operações básicas que precisamos para o seu manuseio, como a inserção, a remoção e a ordenação de dados. Uma característica muito importante destas estruturas de dados é a flexibilidade que existe sobre o formato dos dados que podem ser manuseados, pois não ficamos limitados a guardar um determinado tipo específico de objeto.

Por outro lado, de forma a podermos utilizar vários tipos de objetos de maneira segura, a linguagem Java introduziu o conceito de genéricos, que nos permite fazer operações com objetos de vários tipos com “type safety” em tempo de compilação. Com base nisso, vamos ver neste artigo como está construída e como podemos utilizar a plataforma de coleções e genéricos da linguagem Java, recursos empregados em qualquer aplicação.

É muito comum escrevermos programas que se comuniquem passando informações através de objetos. Mas quando precisamos enviar vários objetos para serem processados, torna-se dispendioso fazer o seu envio de forma individual.

Melhor seria fazer um único envio de vários objetos agrupados e receber uma única resposta, ou uma série de respostas agrupadas em um único objeto. Pensando nisso, a plataforma Java nos disponibiliza um framework de Collections.

Uma coleção, também designada de container, é um simples objeto que agrupa múltiplos objetos (conhecidos como elementos da coleção) numa só unidade.

Estas coleções são utilizadas para guardar, retornar, manipular e transmitir dados agregados de maneira simples e estão disponíveis no framework de Collections do Java, que possui uma arquitetura unificada e criada para permitir que coleções sejam manipuladas de forma independente dos detalhes de suas implementações.

As principais vantagens do framework de Collections são:

· Reduz o esforço de programação, fornecendo estruturas de dados e algoritmos de modo que não tenhamos que escrevê-los;

· Por fornecer implementações de estruturas de dados e algoritmos de alto desempenho, viabiliza um aumento de performance;

· Proporciona interoperabilidade entre APIs não relacionadas, ao estabelecer uma linguagem comum para passar informações através de coleções;

· Reduz o esforço necessário para aprender sobre as APIs, já que as coleções que nos são disponibilizadas são comuns em várias linguagens de programação;

· Promove a reutilização de software, com interfaces padrão para coleções e algoritmos de dados.

A API Collections

Para podermos usufruir de todas estas vantagens, temos disponível na linguagem Java vários tipos de objetos que implementam diversos tipos diferentes de coleções.

Cada tipo de coleção tem suas características específicas e, de forma a organizá-las, a API de coleções do Java foi dividida em interfaces que agrupam as classes das implementações em um dos seguintes tipos:

· Collection: É a raiz da hierarquia das coleções. Define um agrupamento de objetos, denominados de elementos. As suas implementações determinam quando existe ou não ordenação e quando é possível ou não fazer a inserção duplicada de elementos;

· Set: Uma coleção onde não são permitidas inserções de elementos repetidos e onde seus elementos não são ordenados. Deste modo, não existe pesquisa através de índices;

· List: Uma coleção ordenada, onde são permitidas inserções duplicadas. Os elementos podem ser inseridos em uma posição específica, o que permite fazer pesquisas através de índices. Na sua essência, pode ser visto como um array de tamanho variável;

· Queue: Esta interface define uma estrutura de fila, que tipicamente (mas não necessariamente) guarda seus elementos na ordem em que foram inseridos. Ela define o sistema conhecido como “first-in, first out”, onde os elementos são inseridos no fim da fila e removidos do seu início;

· Deque: Do inglês “Double Ended QUEue”, representa uma fila com duas terminações. Enquanto uma queue apenas permite inserções no fim da fila e remoções do seu início, um deque permite que inserções e remoções sejam feitas no início e no fim da fila, ou seja, um objeto que implemente Deque pode ser usado tanto como uma fila FIFO (first-in, first-out), quanto uma fila LIFO (last-in, first-out).

A interface Map

A interface Map representa um tipo abstrato de coleções de objetos e uma instância de uma classe que implemente esta interface é um objeto que mapeia chaves a valores, ou seja, para uma determinada chave (única) existe um valor (único) associado.

Assim sendo, um Map não pode ter chaves repetidas e cada chave está associada a, no máximo, um valor.

Mas, se Map é vista como uma coleção, então porque não estende a interface Collection? Esta é uma opção de desenho dos desenvolvedores da linguagem Java, que consideraram que Maps não são coleções e coleções não são Maps.

Maps são pares de chave-valor, que não se encaixam na definição de coleções, que são constituídas por elementos simples. No entanto, ao mesmo tempo, podem ser vistas como coleções de chaves/valores, ou pares, e este fato é refletido nas suas operações de coleções, a saber: keySet(), que retorna uma estrutura Set com as chaves de mapeamento dos objetos contidos na estrutura Map; entrySet(), que retorna uma estrutura Set com os pares de chave-valor dos mapeamentos do objeto Map; e values(), que retorna uma estrutura do tipo Collection com todos os valores do mapeamento.

A Listagem 1 mostra um exemplo de código que cria um objeto Hashtable, que implementa a interface Map e mostra as operações de coleções que Map possui com seus respectivos outputs.

Listagem 1. Exemplo com operações de coleções que existem num objeto do tipo Map.


  1      public static void testHashTable() {
  2            Map<String, String> m = new Hashtable<>();
  3            m.put("J", "José");
  4            m.put("M", "Miguel");
  5            m.put("B", "Bruno");
  6            m.put("F", "Fernando");
  7            m.put("A", "Alex");
  8
  9            System.out.println("Key set:   " + m.keySet().toString());
  10            System.out.println("Entry set: " + m.entrySet().toString());
  11           System.out.println("Values:    " + m.values().toString());
  12     }
   
  -- Output: 
  <p align="left">Key set:   [A, J, F, B, M]
  <p align="left">Entry set: [A=Alex, J=José, F=Fernando, B=Bruno, M=Miguel]
  <p align="left">Values:    [Alex, José, Fernando, Bruno, Miguel]

Temos ainda duas interfaces de coleção, a SortedList e a SortedMap, que são meramente versões classificadas/ordenadas das interfaces Set e Map, respectivamente (neste ponto há uma “confusão” sobre a palavra ordenada que será explicada a seguir). Não vamos detalhar estas interfaces porque o mais importante agora é entender o conceito de cada estrutura (Set, List, Queue, Deque e Map) e não as suas variações.

A Figura 1 nos mostra a hierarquia das principais interfaces que implementam Collection e a interface Map.

Figura 1. Hierarquia das principais interfaces que implementam Collection.

Ordernado e classificado

Ao explicar as estruturas SortedList e ...

Quer ler esse conteúdo completo? Tenha acesso completo