Você está na página 1de 14

O Collections Framework

"Desde a verso 1.2 do JDK (depois que o renomearam para Java 2 SDK), a plataforma J2SE
inclui um framework de colees (a Collections Framework). Uma coleo um objeto que
representa um grupo de objetos. Um framework de colees uma arquitetura unificada para
representao e manipulao de colees, permitindo que elas sejam manipuladas
independentemente dos detalhes de sua implementao.
As principais vantagens do collections framework so:
- Reduo do esforo de programao, fornecendo estruturas de dados e algoritmos teis, para que
no seja necessrio reescrev-los.
- Aumento da performance, fornecendo implementaes de alta performance. Como as vrias
implementaes de cada interface so substituveis, os programas podem ser facilmente refinados
trocando-se as implementaes.
- Interoperabilidade entre APIs no relacionadas, estabelecendo uma linguagem comum para
passagem de colees.
- Reduo do esforo de aprendizado de APIs, eliminando a necessidade de se aprender vrias
APIs de colees diferentes.
- Reduo do esforo de projetar e implementar APIs, eliminando a necessidade de se criar APIs de
colees prprias.
- Promover o reso de software, fornecendo uma interface padro para colees e algoritmos para
manipul-los.
O Collections Framework consiste em:
- Interfaces de colees - representam diferentes tipos de coleo, como conjuntos, listas e arrays
associativos. Estas interfaces formam a base do framework.
- Implementao de uso geral - implementaes bsicas das interfaces de colees.
- Implementaes legadas - as classes de colees de verses anteriores, Vector e Hashtable, foram
remodeladas para implementar as interfaces de colees (mantendo a compatibilidade).
- Implementaes de wrappers - adicionam funcionalidades, como sincronizao, a outras
implementaes.
- Implementaes convenientes - "mini-implementaes" de alta performance das interfaces de
colees.
- Implementaes abstratas - implementaes parciais das interfaces de colees, para facilitar a
criao de implementaes personalizadas.
- Algoritmos - mtodos estticos que performam funes teis sobre colees, como a ordenao
de uma lista.

- Utilitrios de Arrays - funes utilitrias para arrays de primitivas e objetos. Estritamente


falando, no pertence ao Collections Framework, porm, esta funcionalidadefoi adicionada
plataforma Java ao mesmo tempo, e utiliza parte da mesma infraestrutura." (traduo livre de um
trecho da documentao do JDK)

Colees
Collection
Interface base para todos os tipos de coleo. Ela define as operaes mais bsicas para colees de
objetos, como adio (add) e remoo (remove) abstratos (sem informaes quanto ordenao dos
elementos), esvaziamento (clear), tamanho (size), converso para array (toArray), objeto de iterao
(iterator), e verificaes de existncia (contains e isEmpty).

List
Interface que extende Collection, e que define colees ordenadas (sequncias), onde se tem o controle
total sobre a posio de cada elemento, identificado por um ndice numrico. Na maioria dos casos, pode
ser encarado como um "array de tamanho varivel" pois, como os arrays primitivos, acessvel por
ndices, mas alm disso possui mtodos de insero e remoo.

ArrayList
Implementao de List que utiliza internamente um array de objetos. Em uma insero onde o
tamanho do array interno no suficiente, um novo array alocado (de tamanho igual a 1.5 vezes
o array original), e todo o contedo copiado para o novo array. Em uma insero no meio da lista
(ndice < tamanho), o contedo posterior ao ndice deslocado em uma posio. Esta
implementao a recomendada quando o tamanho da lista previsvel (evitando realocaes) e
as operaes de insero e remoo so feitas, em sua maioria, no fim da lista (evitando
deslocamentos), ou quando a lista mais lida do que modificada (otimizado para leitura aleatria).
LinkedList
Implementao de List que utiliza internamente uma lista encadeada. A localizao de um
elemento na n-sima posio feita percorrendo-se a lista da ponta mais prxima at o ndice
desejado. A insero feita pela adio de novos ns, entre os ns adjacentes, sendo que antes
necessria a localizao desta posio. Esta implementao recomendada quando as
modificaes so feitas em sua maioria tanto no incio quanto no final da lista, e o percorrimento
feito de forma sequencial (via Iterator) ou nas extremidades, e no aleatria (por ndices). Um
exemplo de uso como um fila (FIFO - First-In-First-Out), onde os elementos so retirados da
lista na mesma sequncia em que so adicionados.
Vector

Implementao de List com o mesmo comportamento da ArrayList, porm, totalmente


sincronizada. Por ter seus mtodos sincronizados, tem performance inferior ao de uma ArrayList,
mas pode ser utilizado em um ambiente multitarefa (acessado por vrias threads) sem perigo de
perda da consistncia de sua estrutura interna.
Em sistemas reais, essa sincronizao acaba adicionando um overhead desnecessrio, pois mesmo
quando h acesso multitarefa lista (o que no acontece na maioria das vezes), quase sempre
preciso fazer uma nova sincronizao nos mtodos de negcio, para \'atomizarem\' operaes
seguidas sobre o Vector. Por exemplo, uma chamada ao mtodo contains(), seguida de uma
chamada do mtodo add() caso o elemento no exista, podem causar condies de corrida, se h
acessos de vrioas threads ao mesmo tempo. Assim, acaba sendo necessria uma sincronizao
adicional, englobando estas duas operaes e tornando desnecessria a sincronizao inerente da
classe.
Portanto, a no ser que hajam acessos simultneos de vrias threads lista, e a sincronizao
simples, provida pela classe Vector, seja o bastante, prefira outras implementaes como ArrayList
e LinkedList, que oferecem performance superior.
Stack
Implementao de List que oferece mtodos de acesso para uso da lista como uma pilha (LIFO Last-In-First-Out), como push(), pop() e peek(). Estende Vector, portanto herda as vantagens e
desvantagens da sincronizao deste. Pode ser usado para se aproveitar as implementaes das
operaes especficas de pilha.
Set
Interface que define uma coleo, ou conjunto, que no contm duplicatas de objetos. Isto , so ignoradas
as adies caso o objeto ou um objeto equivalente j exista na coleo. Por objetos equivalentes, entendase objetos que tenham o mesmo cdigo hash (retornado pelo mtodo hashCode()) e que retornem
verdadeiro na comparao feita pelo mtodo equals().
No garantida a ordenao dos objetos, isto , a ordem de iterao dos objetos no necessariamente tem
qualquer relao com a ordem de insero dos objetos. Por isso, no possvel indexar os elementos por
ndices numricos, como em uma List.

HashSet
Implementao de Set que utiliza uma tabela hash (a implementao da Sun utiliza a classe
HashMap internamente) para guardar seus elementos. No garante a ordem de iterao, nem que a
ordem permanecer constante com o tempo (uma modificao da coleo pode alterar a ordenao
geral dos elementos). Por utilizar o algoritmo de tabela hash, o acesso rpido, tanto para leitura
quanto para modificao.

LinkedHashSet
Implementao de Set que estende HashSet, mas adiciona previsibilidade ordem de iterao
sobre os elementos, isto , uma iterao sobre seus elementos (utilizando o Iterator) mantm a
ordem de insero (a insero de elementos duplicados no altera a ordem anterior). Internamente,
mantida uma lista duplamente encadeada que mantm esta ordem. Por ter que manter uma lista

paralelamente tabela hash, a modificao deste tipo de coleo acarreta em uma leve queda na
performance em relao HashSet, mas ainda mais rpida que uma TreeSet, que utiliza
comparaes para determinar a ordem dos elementos.

SortedSet
Interface que estende Set, adicionando a semntica de ordenao natural dos elementos. A posio dos
elementos no percorrimento da coleo determinado pelo retorno do mtodo compareTo(o), caso os
elementos implementem a interface Comparable, ou do mtodo compare(o1, o2) de um objeto auxiliar que
implemente a interface Comparator.

TreeSet
Implementao de SortedSet que utiliza internamente uma TreeMap, que por sua vez utiliza o
algoritmo Red-Black para a ordenao da rvore de elementos. Isto garante a ordenao
ascendente da coleo, de acordo com a ordem natural dos elementos, definida pela
implementao da interface Comparable ou Comparator. Use esta classe quando precisar de um
conjunto (de elementos nicos) que deve estar sempre ordenado, mesmo sofrendo modificaes.
Para casos onde a escrita feita de uma s vez, antes da leitura dos elementos, talvez seja mais
vantajoso fazer a ordenao em uma List, seguida de uma cpia para uma LinkedHashSet
(dependendo do tamanho da coleo e do nmero de repeties de elementos).

Map
Interface que define um array associativo, isto , ao invs de nmeros, objetos so usados como chaves
para se recuperar os elementos. As chaves no podem se repetir (seguindo o mesmo princpio da interface
Set), mas os valores podem ser repetidos para chaves diferentes. Um Map tambm no possui
necessariamente uma ordem definida para o percorrimento.

HashMap
Implementao de Map que utiliza uma tabela hash para armazenar seus elementos. O tempo de
acesso aos elementos (leitura e modificao) constante (muito bom) se a funo de hash for bem
distribuda, isto , a chance de dois objetos diferentes retornarem o mesmo valor pelo mtodo
hashCode() pequena.
LinkedHashMap
Implementao de Map que estende HashMap, mas adiciona previsibilidade ordem de iterao
sobre os elementos, isto , uma iterao sobre seus elementos (utilizando o Iterator) mantm a
ordem de insero (a insero de elementos duplicados no altera a ordem anterior). Internamente,
mantida uma lista duplamente encadeada que mantm esta ordem. Por ter que manter uma lista
paralelamente tabela hash, a modificao deste tipo de coleo acarreta em uma leve queda na

performance em relao HashMap, mas ainda mais rpida que uma TreeMap, que utiliza
comparaes para determinar a ordem dos elementos.
Hashtable
Assim como o Vector, a Hashtable um legado das primeiras verses do JDK, igualmente
sincronizado em cada uma de suas operaes. Pelos mesmos motivos da classe Vector, d
preferncia a outras implementaes, como a HashMap, LinkedHashMap e TreeMap, pelo ganho
na performance.
Properties
Classe que estende Hashtable, especializada para trabalhar com Strings. No propriamente uma
coleo (j que se restringe basicamente a Strings), mas serve como exemplo de uma
implementao especializada da interface Map.
IdentityHashMap
Implementao de Map que intencionalmente viola o contrato da interface, utilizando a identidade
(operador ==) para definir equivalncia das chaves. Esta implementao deve ser usada apenas em
casos raros onde a semntica de identidade referencial deve ser usada para equivalncia.
WeakHashMap
Implementao de Map que utiliza referncias fracas (WeakReference) como chaves, permitindo a
desalocao pelo Garbage Collector dos objetos nela contidos. Esta classe pode ser usada como
base para a implementao de caches temporrios, com dados automaticamente desalocados em
caso de pouca utilizao.
SortedMap
Interface que estende Map, adicionando a semntica de ordenao natural dos elementos, anlogo
SortedSet. Tambm adiciona operaes de partio da coleo, com os mtodos headMap(k) - que retorna
um SortedMap com os elementos de chaves anteriores a k -, subMap(k1,k2) - que retorna um SortedMap
com os elementos de chaves compreendidas entre k1 e k2 - e tailMap(k) - que retorna um SortedMap com
os elementos de chaves posteriores a k.

TreeMap
Implementao de SortedMap que utiliza o algoritmo Red-Black para a ordenao da rvore de
elementos. Isto garante a ordenao ascendente da coleo, de acordo com a ordem natural dos
elementos, definida pela implementao da interface Comparable ou Comparator. Use esta classe
quando precisar de um conjunto (de elementos nicos) que deve estar sempre ordenado, mesmo
sofrendo modificaes. Anlogo ao TreeSet, para casos onde a escrita feita de uma s vez, antes
da leitura dos elementos, talvez seja mais vantajoso fazer a ordenao em uma List, seguida de
uma cpia para uma LinkedHashSet (dependendo do tamanho da coleo e do nmero de
repeties de chaves).

Interfaces auxiliares
O framework Collections define ainda uma srie de interfaces auxiliares, que definem operaes de
objetos retornados por mtodos das interfaces de colees.
Iterator
Interface que define as operaes bsicas para o percorrimento dos elementos da coleo. Utiliza o pattern
de mesmo nome (Iterator, GoF), desacoplando o cdigo que utiliza as colees de suas estruturas internas.
possvel remover elementos da coleo original utilizando o mtodo remove(), que remove o elemento
atual da iterao, mas esta operao de implementao opcional, e uma UnsupportedOperationException
ser lanada caso esta no esteja disponvel.
ListIterator
Interface que estende Iterator, adicionando funes especficas para colees do tipo List. obtida atravs
do mtodo listIterator() de uma List, e possui operaes de percorrimento em ambos os sentidos
(permitido pela indexao dos elementos feita pela List).
Comparable
Interface que define a operao de comparao do prprio objeto com outro, usado para definir a ordem
natural dos elementos de uma coleo. Pode ser usado caso os objetos que sero adicionados na coleo j
implementem a interface (Integer, Double, String, etc.), ou sero implementados pelo programador, que
tem a chance de embutir esta interface em seu cdigo.
Comparator
Interface que define a operao de comparao entre dois objetos por um objeto externo. utilizado
quando os objetos a serem adicionados no podem ser modificados para aceitarem a interface Comparable
(so de uma biblioteca de terceiros, por exemplo), ou necessria a troca da estratgia de ordenao em
tempo de execuo (ordenao das linhas de uma tabela, por exemplo). Esta interface prov maior
flexibilidade, sem custo adicional significativo. Prefira seu uso, ao invs da interface Comparable, a no
ser que esta seja necessria (isto , voc usa uma classe que espera objetos que a implementem) ou se a
prpria semntica dos objetos exija esa ordem natural (o que bem subjetivo e especfico do
domnio/sistema).
Enumeration
\'Ancestral\' da interface Iterator, que prov as mesmas funes, a no ser a retirada de elementos da
coleo. Os nomes de seus mtodos so bem mais longos - hasMoreElements() e nextElement() contra
hasNext() e next() - o que dificulta a digitao e a leitura do cdigo. utilizada basicamente apenas nas
classes Vector e Hashtable, podendo ser praticamente ignorada e substituda pela interface Iterator.

RandomAccess
Interface marcadora (marker interface), que apenas assinala que determinadas implementaes de List so
otimizadas para acesso aleatrio (por ndice numrico, ao invs de iterators). Ista informao pode ser
usada por algumas classes, para que estas possam alterar suas estratgias internas para ganho de
performance.

Classes Utilitrias
Classes utilitrias, como assumidas aqui, so classes que possuem apenas mtodos estticos, provendo
algoritmos comuns.
Collections
Oferece mtodos que efetuam operaes sobre colees. Algumas operaes disponveis so: busca
binria em listas; substituio dos elementos de uma lista por um determinado objeto; busca pelo menor
ou maior elemento (de acordo com a ordem natural definida pelas interfaces Comparable ou Comparator);
inverso de uma lista; embaralhamento; deslocamento dos elementos; obteno de colees sincronizadas
ou imutveis, baseadas em colees j existentes (atravs do pattern Decorator).
Arrays
Classe utilitria que oferece operaes sobre arrays, incluindo: ordenao, procura binria, comparao
entre arrays, preenchimento, clculo do hashCode baseados nos elementos de um array, transformao em
String e o invlucro de um array por uma implementao de tamanho fixo de List.

Programando por Interfaces


O Collections framework do Java nos fornece toda uma infraestrutura para estruturas de dados. E, por usar
interfaces bsicas bem definidas (Collection, List, Set, SortedSet, Map, SortedMap), cria tambm
abstraes que aumentam a flexibilidade e a facilidade de modificao.
Quando programamos usando estas classes, devemos sempre referenci-las pelas interfaces. Algum pode
dizer: "Mas no d pra instanciar interfaces!" Claro que no. Quando precisamos instanciar uma coleo,
utilizamos a implementao concreta mais apropriada, mas os tipos de parmetros e retornos dos mtodos
devem sempre ser uma destas interfaces bsicas.
Por exemplo, no cdigo seguinte:

view plainprint?
1. private Vector listaDeCompras;
2. public void setListaDeCompras(Vector lista) {
3.

this.listaDeCompras = lista;

4. }
5. public Vector getListaDeCompras() {
6.

return this.listaDeCompras;

7. }

Suponha que tenhamos notado que no h acesso concorrente a este objeto, e a sincronizao inerente do
Vector est impactando na performance do sistema. Para alterarmos o tipo de Vector para ArrayList,
eliminando o overhead desnecessrio da sincronizao, temos que alterar todas as classes que utilizam este
mtodo, pois elas passam e esperam um Vector, no um ArrayList.
Ou pior: suponha que estas classes que utilizam nossa lista de compras (criadas por outras equipes,
portanto, mais difceis de serem alteradas) tambm tm suas prprias estruturas internas de dados,
utilizando a classe LinkedList. O inferno est mais prximo do que voc imagina! Para passar parmetros
ou receber valores preciso fazer converses entre colees diferentes, copiando os elementos de uma
para outra, aumentando ainda mais o problema de performance, alm de dificultar a leitura e a
manuteno do cdigo.
Nestes casos, se no lugar de Vector tivssemos usado a interface List, bastaria alterar o local de
instanciao da classe, que todo o resto do cdigo teria automaticamente a nova implementao, sem
modificaes. Uma coleo criada em um componente poderia facilmente ser utilizada por outro, pois
tudo o que ele espera uma implementao de List, e no uma classe concreta.
Portanto, utilize interfaces sempre que puder, principalmente em assinaturas de mtodos pblicos, e limite
ao mximo referncias a classes concretas, mesmo internamente na classe.
E que interface usar?
Temos agora pelo menos seis interfaces para escolher: Collection, List, Set, SortedSet, Map e SortedMap.
Se acrescentarmos as auxiliares de acesso coleo, temos ainda a Iterator e a ListIterator. Qual delas
usar?

A Collection a mais genrica, portanto a mais indicada sempre, certo?

Errado! Por ser to genrica, suas operaes so muito restritas, dificultando sua manipulao. Por
exemplo, ela no permite o acesso direto a um elemento, toda a leitura deve ser feita atravs de seu
Iterator. Se a coleo ser sempre lida como uma sequncia de elementos, e o acesso aleatrio (por ndice)
no faz sentido, isto no problema. Mas se este tipo de acesso necessrio (ou mesmo conveniente), faz
mais sentido usar uma interface List.
Este um problema sem uma resposta definitiva, pois depende muito de cada caso. Mas posso listar
algumas regras bsicas, obtidas da minha prpria experincia. No que isso seja grande coisa, mas vale a
tentativa. :P
- A interface Collection normalmente usada para conjuntos descartveis, isto , que vo ser lidos
apenas uma vez, e no guardados internamente e manipulados (no mximo copiados para uma
outra estrutura).
- A interface Set serve mais como um marcador da semntica esperada, pois ela no acrescenta
nenhuma operao Collection.
- As interfaces SortedSet e SortedMap servem para forar um contrato, de que os elementos da
coleo viro ordenados. Aparecem, principalmente, como parmetros de mtodos que esperam
por esta ordenao. Porm, na maioria das vezes, as classes TreeSet e TreeMap sero usadas
apenas localmente, como containers temporrios de ordenao.

Exemplos de uso:
Loop tpico em uma Collection, usando o Iterator:
view plainprint?
1. Iterator it = colecao.iterator();
2. while (it.hasNext()) {
3.

String item = (String) it.next();

4.

System.out.println(item);

5. }

Loop tpico em um Map, usando o Iterator:


view plainprint?
1. Map mapa = new HashMap();
2. Iterator itChaves = mapa.keySet().iterator();
3. while (itChaves.hasNext()) {
4.

Object chave = itChaves.next();

5.

Object valor = mapa.get(chave);

6.

System.out.println(chave + " = " + valor);

7. }

Usando um iterator para retirar elementos de uma coleo:


view plainprint?
1. Iterator it = listaCores.iterator();
2. while (it.hasNext()) {
3.

String item = (String) it.next();

4.

if (item.charAt(0) == \'v\') { //retirando as cores que comeam com \'v\'

5.
6.

it.remove();
}

7. }

Utilizando um TreeSet para listar o contedo de um Map/Properties de maneira ordenada:


view plainprint?
1. Properties p = new Properties();
2. //...
3. Iterator it = new TreeSet(p.keySet()).iterator(); //ordena as chaves antes de criar o iterator
4. while (it.hasNext()) {
5.

String key = (String) it.next();

6.

System.out.println(key + "=" + p.getProperty(key));

7. }

Inicializao de uma Collection:

view plainprint?
1. // Verso normal:
2. List listaCores = new ArrayList();
3. listaCores.add("vermelho");
4. listaCores.add("verde");
5. listaCores.add("amarelo");
6. listaCores.add("branco");
7.
8. // Verso abreviada utilizando um array
9. List listaCores = new ArrayList(Arrays.asList(new String[] {
10.

"vermelho", "verde", "amarelo", "branco" }));

Criando e ordenando uma Collection:


view plainprint?
1. List listaCores = new ArrayList(Arrays.asList(new String[] {
2.
"vermelho", "verde", "amarelo", "branco" }));
3.
4. Collections.sort(listaCores);

Criando e ordenando uma Collection:


view plainprint?
1. List listaCores = new ArrayList(Arrays.asList(new String[] {
2.
"vermelho", "verde", "amarelo", "branco" }));
3.
4. Collections.sort(listaCores);

Interseco de conjuntos utilizando Set:


view plainprint?
1. Set coresQuentes = new HashSet(Arrays.asList(new String[] {
2.
"vermelho", "laranja", "amarelo" }));
3.
4. Set conjuntoCores = new HashSet(Arrays.asList(new String[] {
5.

"vermelho", "verde", "amarelo", "branco" }));

6.
7. conjuntoCores.retainAll(coresQuentes); // conjuntoCores == {"vermelho", "amarelo"}

Você também pode gostar