
Clique aqui para ler esse artigo em PDF.![]()
Coleções em Ordem
Gerenciando e ordenando dados na camada de objetos
Desenvolva uma aplicação web fazendo uso dos recursos de ordenação de objetos oferecidos pelas classes e interfaces da API de coleções.
Neste artigo, vamos abordar a API de coleções Java, uma das mais úteis e importantes do Java SE, explorando principalmente seus recursos para ordenação. Serão apresentados alguns tipos de coleções fundamentais, bem como as classes utilitárias Arrays, Collections, Comparable e Comparator. Para exemplificar, criaremos uma aplicação web que exibe, de forma ordenada, uma listagem de clientes obtidos de uma base de dados. Clicando sobre uma das colunas da listagem, o usuário pode ordenar os clientes por vários campos, sem a necessidade de executar novas consultas no banco de dados.
Introdução ao uso de coleções
Em termos gerais, uma coleção pode ser entendida como um grupo de objetos com características em comum. A forma mais básica de se trabalhar com grupos de objetos em Java é por meio de arrays. Mas a manipulação de arrays com esse objetivo não é uma tarefa simples – especialmente nas operações de inserção, remoção e ordenação de objetos.
Para a manipulação de grupos de objetos, portanto, os arrays não são práticos o suficiente. Isso motivou os criadores de Java a definir, desde o Java 1.0, coleções dinâmicas como Vector e Hashtable. E no Java 2, veio a definição de uma arquitetura unificada pra representar e manipular coleções de objetos em Java – o Java Collections Framework. Formada por interfaces, classes abstratas e implementações focadas em vários cenários de uso, o framework de coleções traz muitas facilidades importantes. Com ele, deixa de ser necessário implementar métodos de inserção, remoção, ordenação e busca, por exemplo. Esses recursos já são oferecidos, com implementações eficientes e bem testadas.
Basicamente, o framework de coleções é composto por:
· Interfaces de coleções, que representam os diferentes tipos de coleções (Collection, Set, List, Queue, Map etc.);
· Implementações das interfaces, que podem ser utilizadas pelos programadores para criar instâncias das coleções prontas para uso (HashSet, ArrayList, PriorityQueue etc.);
· Implementações legadas, que são as classes que já existiam antes da criação do framework (Vector e Hashtable);
· Classes abstratas, implementações parciais das interfaces para facilitar implementações customizadas (AbstractList, AbstractSet, etc.);
· Classes utilitárias, contendo métodos úteis para manipulação de coleções, tais como métodos de ordenação e busca (ex.: Collections).
As interfaces Map e Collection formam a base do framework. Collection permite a manipulação padronizada de coleções de tipos variados (List, Set ou Queue). Também define os métodos minimamente necessários para todas as coleções, tais como add(Object o), remove(Object o), contains(Object o), size(), entre outros. A Figura 1 apresenta um diagrama com as principais coleções e classes utilitárias que fazem parte do framework. Os itens desse diagrama são descritos na Tabela 1 (interfaces) e na Tabela 2 (classes). Este artigo aborda principalmente as interfaces descendentes de Collection.
Todas as interfaces de coleções, a partir do Java 5, são genéricas. Isso significa que, quando se cria uma instância de um subtipo de Collection ou de Map, é possível especificar o tipo de objeto que a coleção pode armazenar. Assim, se pode verificar se os objetos inseridos na coleção são do tipo correto em tempo de compilação. Para nos concentrar no uso e ordenação das coleções, não detalhamos o recurso de tipos genéricos, mas o usaremos ao definir nossas coleções.
Uma das vantagens oferecidas pelo framework é a capacidade de iterar sobre os elementos de uma coleção (percorrer os elementos um após o outro). A ordem em que essa iteração acontece determina se a coleção é seqüencial ou não-seqüencial, e classificada ou não-classificada. É importante conhecer essa categorização, pois ela pode auxiliar na escolha do tipo de coleção que melhor se aplica a cada cenário de uso.

Figura 1. Subconjunto de interfaces/classes do framework de coleções
|
Interface |
Descrição |
|
java.util.Collection |
Define métodos que permitem manipular qualquer uma das coleções Set, List ou Queue. |
|
java.util.List |
Coleção seqüencial baseada em índices. Pode conter elementos duplicados e nulos. Não classificada. |
|
java.util.Set |
Não é seqüencial nem classificada. Não permite a inclusão de objetos duplicados e aceita apenas um objeto nulo. |
|
java.util.Queue |
Coleção classificada em função da ordem de processamento dos objetos: a ordem mais comum é a FIFO (First In, First Out), mas outras ordenações também são possíveis. |
|
java.util.Map |
Mapa de pares chave/valor. Não permite chaves com valores duplicados e aceita apenas um chave nula. Não é seqüencial, nem classificada. |
|
java.util.SortedSet |
Versão classificada das coleções Set. Faz uso das interfaces Comparable e Comparator. |
|
java.util.SortedMap |
Versão classificada das coleções Map. Também faz uso das interfaces Comparable e Comparator. |
|
java.lang.Comparable e java.util.Comparator |
Usadas para ordenar coleções. |
Tabela 1. Algumas interfaces de coleções
|
Classe |
Descrição | |
|
java.util.ArrayList |
Implementação de List, usando arrays como base. Tem rápida iteração e a ordem é previsível (seqüencial). | |
|
java.util.Vector |
Similar a ArrayList, mas os métodos de acesso aos objetos são thread-safe (ou seja, podem ser usados em aplicações multithreaded sem riscos de problemas de concorrência – mas com perda de performance). | |
|
java.util.LinkedList |
Lista duplamente ligada que implementa as interfaces List e Queue. Especialmente rápida para inserções e remoções. | |
|
java.util.HashSet |
Coleção Set que utiliza código hash para determinar a igualdade dos objetos e para recuperá-los. Eficiência depende da implementação do método hashCode() dos objetos. | |
| ... | ||