C# - Trabalhando com coleções (revisitado)
Vamos repassar neste artigo os principais conceitos e usos das coleções na linguagem C#. |
As coleções são classes especializadas para armazenamento e obtenção de dados muito utilizaas na plataforma .NET.
Se você precisar armazenar vários valores em uma variável, então você pode considerar usar uma coleção. Uma coleção é uma estrutura de dados na memória que pode gerenciar vários itens de maneiras diferentes, podendo possuir algumas funcionalidades compartilhadas.
Os tipos mais comuns no .NET Standard 2.0 para trabalhar com coleções são mostrados na tabela a seguir:
Namespace | Tipos | Descrição |
System.Collections | IEnumerable, IEnumerable<T> | Interfaces e classes base usadas pela coleções |
System.Collections.Generics | List<T>,
Dictionary<T> Queue<T>, Stack<T> |
Estas coleções permitem especificar o tipo que você deseja armazenar usando um parâmetro do tipo genérico |
System.Collections.Concurrent |
BlockingCollection, ConcurrentQueue, ConcurrentDictionary |
Estas
coleções são seguras para usar em cenários de multithread |
System.Collections.Immutable |
ImmutableArray, ImutableList, ImmutableDictionary, ImmutableQueue |
Coleções projetadas para cenários onde o conteúdo da coleção nunca deve mudar |
Características comuns a todas as coleções
Todas as coleções
implementam a interface ICollection; isso significa
que elas devem ter uma propriedade Count para
contar
quantos itens existem.
Por exemplo, se tivéssemos uma coleção chamada
Passageiros, poderíamos fazer o seguinte:
int quantidade =
Passageiros.Count;
Todas as coleções implementam a interface IEnumerable,
o que significa que devem ter um método GetEnumerator
que retorna um objeto que implementa IEnumerator;
isso significa que elas devem ter um método MoveNext
e uma propriedade Value para poder iterar sobre os itens usando a instrução
foreach.
Por exemplo, para
realizar uma ação em todos os itens da coleção dos Passageiros, podemos fazer o
seguinte:
foreach (var passageiro em
Passageiros)
{
// faça algo com cada passageiro
}
Para entender melhor as coleções, podemos analisar as interfaces mais comuns que
elas implementam:
Pela
figura vemos que :
As listas, ou seja, um tipo que implementa IList, são coleções ordenadas, o que significa que implementam ICollection; então elas devem ter :
Temos assim diferentes tipos de coleções : Listas, dicionários, pilhas(stacks), filas (queues), conjuntos (sets) e outras coleções especializadas.
Vejamos um resumo das principais coleções.
Listas (List)
As listas são uma
boa opção quando você deseja controlar manualmente a ordem dos itens em uma
coleção. Cada item em
uma lista possui um índice (ou posição) exclusivo que é atribuído
automaticamente.
Os itens podem ser de qualquer tipo (eles tem que ser todos do mesmo tipo) e os itens podem ser duplicados. Os índices são tipos inteiros e começam em 0, então o o primeiro item em uma lista está no índice 0.
Se um novo item
(por exemplo, New York) for inserido entre Rio e Sydney, o índice de
Sydney será incrementado automaticamente.
Portanto, você deve estar ciente de que o índice de um item pode mudar após a
inserção ou remoção de itens, conforme mostrado na a seguir:
Exemplo:
using System.Collections.Generic; using static System.Console;
var cidades = new List<string>(); WriteLine($"Primeira cidade : {cidades[0]}."); foreach (string cidade in cidades) cidades.RemoveAt(1); WriteLine("Após remover duas cidades"); foreach (string cidade in cidades) ReadLine(); |
Resultado:
Dicionários(Dictionary)
Os dicionários são uma boa escolha quando cada valor (ou item) tem um subvalor único que pode ser usado como uma chave para localizar rapidamente o valor na coleção. (A chave deve ser única)
Se você esta
armazenando uma lista de pessoas, você pode usar o número da identidade como a
chave. Pense na chave
como uma entrada de índice em um dicionário do mundo real. Ela
permite que você encontre rapidamente a definição de uma palavra porque as
palavras (por exemplo, chaves) são mantidas classificadas.
Tanto a chave quanto o valor podem ser de qualquer tipo. Este exemplo usa
strings para ambas:
Exemplo:
using System.Collections.Generic; using static System.Console; var keywords = new Dictionary<string, string>(); keywords.Add("int", "tipo dados inteiro de 32-bit"); WriteLine("Keywords e suas definições"); foreach (KeyValuePair<string, string> item in keywords) WriteLine($"A definição de long é : {keywords["long"]}"); |
Resultado:
Pilhas (Stacks)
As pilhas são uma boa escolha quando você deseja implementar o comportamento último a entrar (Last In), primeiro a sair(FirstOut) (LIFO).
Com uma pilha, você
só pode acessar diretamente um item no topo da pilha, embora possa enumerar para
ler através de toda a pilha de itens. Você não pode, por exemplo, acessar
o segundo item de uma pilha.
Por exemplo, os processadores de texto usam uma pilha para lembrar a sequência
de ações que você fez recentemente, e então quando você pressiona
Ctrl+Z, isso irá desfazer a última ação na pilha, e
então a próxima ação e assim por diante.
Exemplo:
using static System.Console; using System.Collections; Stack planetasRochosos = new Stack(); planetasRochosos.Push("Mercúrio"); foreach (string item in planetasRochosos) ReadLine(); |
Filas (Queues)
As filas são uma boa opção quando você deseja implementar o comportamento primeiro a entrar (First In), primeiro a sair (FirstOut) (FIFO).
Com uma fila, você só
pode acessar diretamente um item na frente da fila, embora possa enumerar para
ler toda a fila de itens. Você não pode, por exemplo, acessar o segundo item de
uma fila.
Por exemplo, processos em segundo plano usam uma fila para processar itens de
trabalho na ordem em que chegam, igual
a pessoas na fila do correio.
Exemplo:
using static System.Console; using System.Collections; Queue planetasRochosos = new Queue(); planetasRochosos.Enqueue("Mercúrio"); foreach (string item in planetasRochosos) ReadLine(); |
Conjuntos (HashSets)
Conjuntos são uma boa escolha quando você deseja realizar operações de conjunto entre duas coleções. Por exemplo, você pode ter duas coleções de nomes de cidades e deseja saber quais nomes aparecem em ambos os conjuntos (conhecido como a interseção entre os conjuntos).
Características da classe HashSet
- A classe
HashSet<T> fornece operações de conjunto de alto
desempenho. Um conjunto é uma coleção que não contém elementos duplicados e
cujos elementos não estão em uma ordem específica.
- A capacidade de um objeto HashSet<T> é o número
de elementos que o objeto pode conter;
- A capacidade de um objeto HashSet<T> aumenta
automaticamente conforme os elementos são adicionados ao objeto;
- Uma coleção HashSet<T> não é classificada e
não pode conter elementos duplicados;
- A classe HashSet<T> fornece muitas operações
matemáticas de conjuntos, como adição de conjuntos
(uniões) e subtração de conjuntos.
Exemplo:
using System;
using System.Collections.Generic;
HashSet<string> nomes = new HashSet<string> {"Macoratti","Miriam","Janice"};
//valores duplicados não são incluidos
nomes.Add("Macoratti");
foreach (var name in nomes)
{
Console.WriteLine(name);
}
Console.ReadKey();
|
Recapitulamos assim, de forma resumida, alguns dos conceitos básicos das principais coleções existentes na plataforma .NET.
E estamos conversados.
"E eu, quando o vi,
caí a seus pés como morto; e ele pôs sobre mim a sua destra, dizendo-me: Não
temas; Eu sou o primeiro e o último; E o que vivo e fui morto, mas eis aqui
estou vivo para todo o sempre. Amém. E tenho as chaves da morte e do inferno."
Apocalipse 1:17,18
Referências:
-
C# - Tasks x Threads.
Qual a diferença -
-
VB .NET - Datas,
horas: conceitos e operações
-
C# - Programação
Assíncrona como : Asycn e Task
-
O tratamento de datas
no VB.NET
-
C# - Obtendo a data e
a hora por TimeZone
-
C# - O Struct Guid - Macoratti.net
-
DateTime -
Macoratti.net
-
Formatação de data e
hora para uma cultura .
-
-
C# - Calculando a
diferença entre duas datas
-
C# - Fundamentos :
Definindo DateTime como Null