• Nenhum resultado encontrado

Benefícios do Java Collections Framework O Java Collections Framework oferece os seguintes benefícios:

No documento Java Fundamentos (páginas 102-108)

Redução do esforço de programação: Ao fornecer estruturas úteis de dados e algoritmos, a estrutura Collections libera o programador para concentrar nas partes importantes de seu programa. Ao facilitar a interoperabilidade entre APIs não relacionadas, o Java Collections Framework libera-o de escrever objetos adaptadores ou código de conversão para conectar APIs.

Aumenta a velocidade e a qualidade do programa: Este Collections Framework fornece alto desempenho e alta qualidade de implementações de estruturas úteis de dados e algoritmos. As várias implementações de cada interface são intercambiáveis. Com isso, programas pode ser facilmente ajustado trocando implementações de coleta, livrando o programador do trabalho de escrever suas próprias estruturas de dados, ficando com mais tempo para se dedicar a melhorar a qualidade e desempenho dos programas. Permite a interoperabilidade entre APIs não relacionadas: As interfaces de coleta são o

vernáculo pelo qual passa coleções APIs e para trás. Se a minha administração de rede API fornece uma coleção de nomes de nó e se o seu kit de ferramentas GUI espera uma coleção de títulos de coluna, nossas APIs vão interoperar perfeitamente, mesmo que eles foram escritos de forma independente.

Reduz o esforço de aprender e usar novas APIs: APIs naturalmente tomam coleções na entrada e as fornece como saída. No passado, cada API, tinha uma pequena sub-API dedicada a

manipular suas coleções. Houve pouca consistência entre essas coleções ad hoc sub-APIs, assim, você teve que aprender cada um a partir do zero, e era fácil cometer erros quando utilizá-las. Este problema não existe mais com o advento de interfaces padrão de Collections. Reduz o esforço de projetar novas APIs: Este é o outro lado da vantagem anterior

descrita. Designers e implementadores não tem que reinventar a roda cada vez que criar uma API que se baseia em coleções. Em vez disso, eles podem usar interfaces padrão de Collections.

Promove a reutilização de software: Novas estruturas de dados que estejam em conformidade com as interfaces padrão de Collections são, por natureza reutilizável. O mesmo vale para novos algoritmos que operam em objetos que implementam essas interfaces.

Com esses e outros objetivos em mente, a Sun criou um conjunto de classes e interfaces conhecido como Collections Framework, que reside no pacote java.util. A API do Collections é robusta e possui diversas classes que representam estruturas de dados avançadas. Por exemplo, não é necessário reinventar a roda e criar uma lista ligada, mas sim utilizar aquela que a Sun disponibilizou.

Figura 8.1 API do Collections.

Listas

Acesso posicional:

Manipula elementos baseado na sua posição numérica na lista (índice). Pesquisa:

Pesquisa por um objeto específico na lista e retorna a sua posição numérica. Iteração:

Herda a semântica Iterator para tomar vantagem da natureza sequencial da lista. Um primeiro recurso que a API de Collections traz são as listas. Uma lista é uma coleção que permite elementos duplicados e mantém uma ordenação específica entre os elementos. Em outras palavras, você tem a garantia de que, quando percorrer a lista, os elementos serão encontrados em uma ordem pré-determinada, definida na hora da inserção dos mesmos. Ela resolve todos os problemas que levantamos em relação ao array (busca, remoção, tamanho "infinito",...). Esse código já está pronto!

A API de Collections traz a interface java.util.List, que especifica o que uma classe deve ser capaz de fazer para ser uma lista. Há diversas implementações disponíveis, cada uma com uma forma diferente de representar uma lista.

A implementação mais utilizada da interface List é a ArrayList, que trabalha com um array interno para gerar uma lista. Portanto, ela é mais rápida na pesquisa do que sua concorrente, a LinkedList, que é mais rápida na inserção e remoção de itens nas pontas. A interface List possui dois métodos add, um que recebe o objeto a ser inserido e o coloca no final da lista, e um segundo que permite adicionar o elemento em qualquer posição da mesma. Note que, em momento algum, dizemos qual é o tamanho da lista; podemos acrescentar quantos elementos quisermos que a lista cresce conforme for necessário. Toda lista (na verdade, toda Collection) trabalha do modo mais genérico possível. Isto é, não há uma ArrayList específica para Strings, outra para Números, outra para Datas etc. Todos os métodos trabalham com Object.

List lista = new ArrayList(); lista.add("Manoel");

lista.add("Joaquim"); lista.add("Maria");

A interface List e algumas classes que a implementam podem ser vistas no diagrama a seguir:

Figura 8.2 Interface List e classes que a implementam.

Conjuntos

Coleção que não tem elementos duplicados. Podem ser mantidos ordenados (SortedSet) ou não. Modela a abstração matemática para conjuntos.

Contêm os mesmos métodos de Colletion, com a restrição de que não podem ser repetidos.

Um conjunto (Set) funciona de forma análoga aos conjuntos da matemática, ele é uma coleção que não permite elementos duplicados.

Outra característica fundamental dele é o fato de que a ordem em que os elementos são armazenados pode não ser a ordem na qual eles foram inseridos no conjunto. A interface não define como deve ser este comportamento. Tal ordem varia de implementação para

implementação.

Figura 8.3 Interface Set e classes que a implementam.

Um conjunto é representado pela interface Set e tem como suas principais implementações as classes HashSet, LinkedHashSet e TreeSet.

public static void main(String[] args) { Set<String> nomes = new HashSet<String>(); nomes.add("João");

nomes.add("José"); nomes.add("Maria"); nomes.add("Bianca");

System.out.println("Número de elementos: "+nomes.size());

if(nomes.contains("Maria")){

System.out.println("Contém Maria!!!"); }

for(String temp : nomes){ System.out.println(temp); }

Iterator<String> i = nomes.iterator(); while(i.hasNext())

System.out.println(i.next()); }

O uso de um Set pode parecer desvantajoso, já que ele não armazena a ordem, e não aceita elementos repetidos. Não há métodos que trabalham com índices, como o get(int) que as listas possuem. A grande vantagem do Set é que existem implementações, como a HashSet, que possui uma performance incomparável com as Lists quando usado para pesquisa (método contains por exemplo).

Mapas

Um mapa armazena pares (chave, valor) chamados de itens. Chaves e valores podem ser de qualquer tipo.

As chaves armazenadas nos mapas podem estar ordenadas ou não.

A chave é utilizada para achar o elemento de forma rápida, utilizando estruturas especi ais.

Não existem chaves duplicadas em um mapa. Também são conhecidos como dicionários.

Muitas vezes queremos buscar rapidamente um objeto dado alguma informação sobre ele. Um exemplo seria, dada a placa do carro, obter todos os dados do carro. Poderíamos utilizar uma lista para isso e percorrer todos os seus elementos, mas isso pode ser péssimo para a performance, mesmo para listas não muito grandes. Aqui entra o mapa.

Um mapa é composto por um conjunto de associações entre um objeto chave a um objeto valor. java.util.Map é um mapa, pois é possível usá-lo para mapear uma chave a um valor, por exemplo: mapeie à chave "empresa" o valor "Nome da Empresa", ou então mapeie à chave "rua" ao valor "Endereço da Empresa". Semelhante a associações de palavras que podemos fazer em um dicionário.

O método put(Object, Object) da interface Map recebe a chave e o valor de uma nova associação. Para saber o que está associado a um determinado objeto-chave, passa-se esse objeto no método get(Object). Sem dúvida essas são as duas operações principais e mais frequentes realizadas sobre um mapa.

public static void main(String[] args) {

HashMap<String, String> nomes = new HashMap<String, String>(); nomes.put("joao", "João da Silva");

nomes.put("jose", "José Matos"); nomes.put("maria", "Maria das Dores"); nomes.put("bianca", "Bianca Patrícia");

System.out.println("Número de elementos: "+nomes.size());

String temp = nomes.get("bianca"); System.out.println(temp);

}

Um mapa é muito usado para "indexar" objetos de acordo com determinado critério, para podermos buscar esses objetos rapidamente. Um mapa costuma aparecer juntamente com outras coleções, para poder realizar essas buscas!

Ele, assim como as coleções, trabalha diretamente com Objects (tanto na chave quanto no valor), o que tornaria necessário o casting no momento que recuperar elementos. Usando os generics, como fizemos aqui, não precisamos mais do casting. Suas principais

implementações são o HashMap, o TreeMap e o Hashtable.

Apesar do mapa fazer parte do framework, ele não estende a interface Collection, por ter um comportamento bem diferente. Porém, as coleções internas de um mapa são acessíveis por métodos definidos na interface Map.

Figura 8.4 Interface Map e classes que a implementam.

O método keySet() retorna um Set com as chaves daquele mapa e o método values() retorna a Collection com todos os valores que foram associados a alguma das chaves.

Exercício de Fixação 11 – Collections

Para você, os recursos de Collections facilitam a organização e manipulação de conjuntos de dados em aplicações Java?

No documento Java Fundamentos (páginas 102-108)

Documentos relacionados