As coleções em Java estão concentradas principalmente em duas partes, uma está no pacote java.util e a outra está em java.util.concurrent. A última é baseada na primeira e define algumas coleções que implementam funções de sincronização.
Este artigo concentra-se principalmente em vários objetos de coleção em java.util. Os objetos de coleção em Java podem ser divididos em três categorias: Lista, Conjunto e Mapa. O diagrama UML correspondente é o seguinte (incluindo a maioria dos objetos de coleção em java.util):
Visão geral da coleção
Tanto List quanto Set em coleções Java vêm de Collection. É um bom ponto de entrada para aprender coleções. Inclui operações que geralmente são necessárias em coleções.
Adicionar elementos: add/addAll
Limpar a coleção: limpar
Remover elementos: remover/remover todos
Determine se a coleção contém um elemento: contains/containsAll
Determine se a coleção está vazia: isEmpty
Calcule o número de elementos em uma coleção: tamanho
Converta uma coleção em um array: toArray
Obter iterador: iterador
Vejamos um exemplo simples. O código a seguir retornará uma coleção cujos elementos são inteiros gerados aleatoriamente:
cobrança de devolução;
}
1) Use iteradores para percorrer a coleção. Conforme mencionado ao descrever a interface Collection acima, todas as coleções terão um iterador que podemos usar para percorrer a coleção.
Lista em Java é uma extensão eficaz de array. É uma estrutura que pode conter elementos de qualquer tipo se genéricos não forem usados. Se genéricos forem usados, ela só poderá conter elementos do tipo especificado pelos genéricos. Comparado com arrays, a capacidade de List pode ser expandida dinamicamente.
Os elementos da Lista podem ser repetidos e os elementos internos são "ordenados". O "ordenado" aqui não significa classificação, mas significa que podemos especificar a posição de um elemento na coleção.
Os objetos de coleção comumente usados em List incluem: ArrayList, Vector e LinkedList, os dois primeiros são armazenados com base em arrays e os últimos são armazenados com base em listas vinculadas. Entre eles, Vector é thread-safe e os outros dois não são thread-safe.
A lista pode conter nulo, mesmo se forem usados genéricos.
ArrayList pode ser o objeto de coleção mais comumente usado. No código de exemplo acima, também o usamos para instanciar um objeto Collection, portanto não entraremos em detalhes aqui.
Vetor
Um exemplo de Vector é o seguinte. Primeiro, veremos como gerar e gerar Vector:
[9, 29, 32, 54, 12]
tamanho do vetor é 3
[29, 32, 54]
LinkedList usa listas vinculadas para armazenar dados. Seu código de exemplo é o seguinte:
A saída é a seguinte:
nulo
nulo
nulo
o tamanho da lista vinculada é 8
[100, 84, 19, 57, 68, 26, 27, 47]
Set é semelhante a List, ambos são usados para armazenar um único elemento e o número de elementos individuais é incerto. Mas Set não pode conter elementos duplicados. Se dois elementos idênticos forem inseridos em Set, o último elemento não será inserido.
O conjunto pode ser dividido em duas categorias: conjunto não classificado e conjunto classificado. Conjunto não classificado inclui HashSet e LinkedHashSet, e conjunto classificado refere-se principalmente a TreeSet. Entre eles, HashSet e LinkedHashSet podem conter nulo.
HashSet
HashSet é uma coleção apoiada por uma tabela Hash, que não é thread-safe.
Vejamos o exemplo a seguir, que é basicamente igual ao primeiro exemplo com Vector:
para (int i = 0; i < 3; i++)
{
set.add(novo inteiro(100));
}
set.add(nulo);
System.out.println("o tamanho do conjunto é " + set.size());
System.out.println(conjunto);
}
classMyInteger
{
Valor inteiro privado;
público MyInteger (valor inteiro)
{
este.valor = valor;
}
String pública paraString()
{
retornar String.valueOf(valor);
}
hashCode int público()
{
retornar 1;
}
booleano público é igual (objeto objeto)
{
retornar verdadeiro;
}
}
A seguir está o método de teste correspondente:
para (int i = 0; i < 3; i++)
{
set.add(new MeuInteger(100));
}
System.out.println("o tamanho do conjunto é " + set.size());
System.out.println(conjunto);
}
TreeSet é um conjunto que suporta classificação e sua interface pai é SortedSet.
Vamos primeiro dar uma olhada nas operações básicas do TreeSet:
Aleatório r = novo Aleatório();
para (int i = 0; i < 5; i++)
{
set.add(novo Inteiro(r.nextInt(100)));
}
System.out.println(conjunto);
System.out.println(set.first());
System.out.println(set.last());
System.out.println(set.descendenteSet());
System.out.println(set.headSet(new Integer(50)));
System.out.println(set.tailSet(new Integer(50)));
System.out.println(set.subSet(30, 60));
System.out.println(set.floor(50));
System.out.println(set.ceiling(50));
}
[53, 49, 48, 42, 8]
[8, 42, 48, 49]
[53]
[42, 48, 49, 53]
A seguir, primeiro redefinimos Inteiro:
público MyInteger2 (valor interno)
{
este.valor = valor;
}
público int compareTo(Objeto arg0)
{
MeuInteger2 temp = (MeuInteger2)arg0;
if (temp == null) return -1;
if (temp.valor > este.valor)
{
retornar 1;
}
senão if (temp.valor <este.valor)
{
retornar -1;
}
retornar 0;
}
booleano público é igual (objeto objeto)
{
retornar compararTo(obj) == 0;
}
String pública paraString()
{
retornar String.valueOf(valor);
}
}
O mapa armazena "pares de valores-chave". Semelhante ao Set, existem dois tipos de mapas em Java: classificados e não classificados incluem HashMap, Hashtable e LinkedHashMap, e classificados incluem TreeMap.
Mapa não classificado
Tanto HashMap quanto Hashtable são armazenados na forma de tabelas Hash. HashMap não é seguro para threads, mas Hashtable é seguro para threads. Podemos considerar o HashMap como uma versão "simplificada" do Hashtable.
HashMap pode armazenar nulo, seja para chave ou valor. Hashtable não pode armazenar nulo.
Independentemente de HashMap ou Hashtable, se observarmos seu construtor, descobriremos que ele pode ter dois parâmetros: inicialCapacity e loadFactor. Por padrão, inicialCapacity é igual a 16 e loadFactor é igual a 0,75. Isso está relacionado ao número de elementos que podem ser armazenados na tabela Hash. Quando o número de elementos exceder inicialCapacity*loadFactor, o método rehash será acionado para expandir a tabela hash. Se precisarmos inserir muitos elementos nele, precisaremos ajustar esses dois parâmetros de forma adequada.
Vejamos primeiro um exemplo de HashMap:
map.put(novo Inteiro(1), "a");
map.put(novo Inteiro(2), "b");
map.put(novo Inteiro(3), "c");
System.out.println(mapa);
System.out.println(map.entrySet());
System.out.println(map.keySet());
System.out.println(map.valores());
}
map.put(nulo,nulo);
map.put(nulo,nulo);
map.put(novo Inteiro(4), null);
map.put(novo Inteiro(5), null);
System.out.println(mapa);
System.out.println(map.entrySet());
System.out.println(map.keySet());
System.out.println(map.valores());
}
tabela.put(novo Inteiro(1), "a");
tabela.put(novo Inteiro(2), "b");
tabela.put(novo Inteiro(3), "c");
System.out.println(tabela);
System.out.println(tabela.entrySet());
System.out.println(table.keySet());
System.out.println(tabela.valores());
}
hashTableTest2() vazio estático privado
{
Map<Integer,String> tabela = new Hashtable<Integer, String>();
tabela.put(nulo,nulo);
tabela.put(nulo,nulo);
tabela.put (novo inteiro (4), nulo);
tabela.put (novo inteiro (5), nulo);
System.out.println(tabela);
System.out.println(tabela.entrySet());
System.out.println(table.keySet());
System.out.println(tabela.valores());
}
Sorting Map refere-se principalmente ao TreeMap, que tem uma complexidade de tempo de O(log(n)) ao adicionar, excluir e pesquisar elementos. Não é thread-safe.
Suas características são muito semelhantes às do TreeSet, por isso não entrarei em detalhes aqui.