VB .NET - Usando a coleção genérica Dictionary
Você conhece a classe genérica Dictionary ? Se não conhece deixe-me apresentá-la... |
A classe Dictionary representa uma coleção de chaves e valores. É uma coleção do tipo chave/valor e implementa a interface IDictionary que possui duas coleções no seu interior uma para guardar a chave e outra para guardar o valor.
A sintaxe é a seguinte:
Dictionary (Of (TKey,TValue))
esta presente no namespace : System.Collections.Generic
no assembly : mscorlib (in mscorlib.dll)
onde:
TKey - representa o tipo da chave no dicionário; |
TValue - representa o tipo do valor no dicionário; |
A classe genérica Dictionary é uma classe que mapeia um conjunto de chaves, as quais podem ser de qualquer tipo, para um conjunto de valores, que também podem ser de qualquer tipo sendo que os tipos da chave e o valor não precisam ser idênticos.
Podemos dizer que a coleção Dictionary é uma coleção genérica de tipo que é informado no momento de definir a coleção. É uma coleção do tipo chave/valor onde a chave faz o papel do índice na coleção.
Cada inclusão de um elemento no dicionário consiste de um valor e sua chave associada. O retorno de um valor a partir de sua chave tem um bom desempenho pois a classe Dictionary é implementada como um hashtable.
Obs: No Visual Basic tínhamos o objeto Dictionary que não apresentava um bom desempenho já a classe Dictionary do VB .NET utiliza tabelas de hash internas e apresenta um bom desempenho.
Em todos os exemplos deste artigo eu estou usando o Visual Basic 2008 Express Edition.
Vejamos a seguir algumas das propriedades e características da classe Dictionary:
Para criar um objeto dictionary você deve definir um chave seguida por um valor. O primeiro indica a chave do elemento que deverá ser incluído e o segundo representa o valor que a chave deverá possuir.
Para incluir elementos em um objeto dictionary devemos usar o método Add que calcula o valor do código do hash da chave e então armazena os dados no hash.
Vejamos a seguir um exemplo de como criar um objeto dictionary no Visual Basic 2008:
No código acima estamos criando um objeto Dictionary com chave do tipo String e valores do tipo Integer e e usando o método Add para incluir 6 chaves e valores.
Se você incluir uma chave que já existe no dicionário irá ocorrer uma exceção, para evitar isso você pode verificar se uma chave já existe através do método ContainsKey.
A seguir temos um exemplo que usar o método ContainsKey para verificar se uma chave já existe:
Public Sub UsandoContainsKey() 'Declara um novo Dictionary de chave 'do tipo string e valores integer Dim frutas As New Dictionary(Of String, Integer) ' Inclui duas chaves : banana e maça ListBox1.Items.Add("Incluindo as chaves : banana(15) e maça(7)") frutas.Add("banana", 7) frutas.Add("maça", 15) ' Verficia se uma chave já existe If frutas.ContainsKey("banana") Then ' Escreve um valor para a chave ListBox1.Items.Add("A chave banana já existe") Dim valor As Integer = frutas.Item("banana") ListBox1.Items.Add("Valor = " & valor) End If ' Verifica se a chave ja existe If frutas.ContainsKey("maça") Then ListBox1.Items.Add("A chave maça já existe") Dim valor As Integer = frutas.Item("maça") ListBox1.Items.Add("Valor = " & valor) End If If Not frutas.ContainsKey("abacaxi") Then ListBox1.Items.Add("A chave abacaxi NÃO existe") End If End Sub |
Criamos um Dictionary identificado pelo
nome frutas e incluímos A seguir usamos o método ContainsKey
para verificar se uma chave |
Você também pode armazenar o resultado de uma verificação usando ContainsKey em uma variável boolean e testar a variável usando os operadores = (igual) e <> (diferente).
Os principais métodos da classe Dictionary são:
Nome | Descrição |
---|---|
Add | Inclui uma chave e um valor especificados no dicionário. |
Clear | Remove todas as chaves e valores do dicionário. |
ContainsKey | Determina se o dicionário contém uma chave especifica. |
ContainsValue | Determina se o dicionário contém um valor específico. |
Equals | Determina se o objeto especificado é igual a objeto atual. |
GetEnumerator | Retorna uma enumeração que itera através do dicionário. |
Remove | Remove o valor com a chave especificada do dicionário. |
TryGetValue | Obtém o valor associado com a chave especificada. |
As principais propriedades da Classe Dictionary são:
Nome | Descrição |
---|---|
Count | Obtêm o número do par chave/valor contido em um dicionário. |
Item | Obtêm ou define o valor associado a uma chave específica; |
Keys | Obtêm uma coleção contento as chaves no dicionário; |
Values | Obtêm uma coleção contendo os valores no dicionário. |
Para percorrer um objeto Dictionary podemos usar um loop For Each para percorrer a estrutura KeyValuePair no dicionário. No corpo do laço For/Each você pode acessar os valores da chave e valor de KeyValuePair. Abaixo temos um exemplo:
Public Sub percorreDictionary() ListBox1.Items.Clear() ' Cria um dictionary e inclui 8 chaves do tipo string Dim times As New Dictionary(Of String, Integer) times.Add("Palmeiras", 54) times.Add("Santos", 41) times.Add("Flamento", 49) times.Add("Atlético", 50) times.Add("Internacional", 41) times.Add("Goiás", 48) times.Add("Cruzeiro", 45) times.Add("Gremio", 46) ' Faz um Loop sobre as entradas do dicionário Dim par As KeyValuePair(Of String, Integer) For Each par In times ' Exibe a chave e os valores ListBox1.Items.Add(par.Key & "-" & par.Value) Next End Sub |
Podemos listar o conteúdo de um objeto do tipo DIctionary a partir de uma coleção List de chaves em um Dictionary. Cada instância de Dictionary possui uma propriedade Get com o identificador Keys. Você pode acessar esta coleção e passá-la para o construtor da Lista de chaves. As chaves possuem o mesmo tipo que o Dictionary de origem:
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click ListBox1.Items.Clear() ' Cria 5 chaves e valores no dicionário Dim carros As New Dictionary(Of String, Integer) carros.Add("gol", 12) carros.Add("fiesta", 11) carros.Add("polo", 10) carros.Add("palio", -21) carros.Add("astra", -8) ' Põe a chave em uma lista de strings Dim lista As New List(Of String)(carros.Keys) ' Percorre a lista Dim str As String For Each str In lista ' Imprime a string e também o item ListBox1.Items.Add(str & " - " & carros.Item(str)) Next End Sub |
O resultado obtido é o seguinte:
Neste exemplo criamos um dicionário e em seguida colocamos a chave em uma lista de strings. A seguir percorremos a lista para exibir os itens.
Para remover um item do Dictionary usamos o método Remove. Você precisa passar um parâmetro para este método indicando qual a chave você deseja remover do dicionário. Se você tentar remover uma chave que não existe irá ocorrer uma exceção.
O método ContaisValue retorna um valor booleano que informa se qualquer valor no dicionário é igual ao argumento que você forneceu.
No exemplo abaixo usamos o método ContaisValue para verificar se um valor existe no dicionário e também o método Remove removendo duas chaves existentes:
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click ListBox1.Items.Clear() ' Cria um novo dicionario com 6 chaves Dim flores As New Dictionary(Of String, Integer) flores.Add("rosa", 20) flores.Add("cravo", 21) flores.Add("tulipa", 31) flores.Add("adália", 41) flores.Add("margarida", 61) flores.Add("orquídea", 91) ' Verifica se o valor 21 esta no dicionario If flores.ContainsValue(21) Then ListBox1.Items.Add("O valor 21 esta no dicionário.") ListBox1.Items.Add("O item é = " & flores.Item("tulipa")) End If ' Remove duas chaves: Remove flores.Remove("tulipa") flores.Remove("margarida") ListBox1.Items.Add("Removidas as chaves : tulipa e margarida.") ' Faz um Loop sobre as entradas do dicionário Dim par As KeyValuePair(Of String, Integer) For Each par In flores ' Exibe a chave e os valores ListBox1.Items.Add("Valores e chaves existentes.") ListBox1.Items.Add(par.Key & "-" & par.Value) Next End Sub |
Executando este código iremos obter:
Para contar o número de entradas em um dicionário você pode usar a propriedade Count. A sintaxe usada é : dictionary.Count.
Veja exemplo abaixo onde criamos um dicionário com o nome legumes e efetuamos 3 contagens após realizar algumas operações no dicionário:
Private
Sub
dictionaryCount()
ListBox1.Items.Clear() Dim legumes As New Dictionary(Of String, Integer)() legumes.Add("batata", 1) legumes.Add("cenoura", 4) legumes.Add("repolho", 6) legumes.Add("beterraba", 3) ' Copia as chaves Dim contador1 As Integer = legumes.Count' Remove uma chave. legumes.Remove( "cenoura")' conta as chaves novamente Dim contador2 As Integer = legumes.Count' Limpa o conte£do do dicion rio legumes.Clear() ' conta as chaves novamente Dim contador3 As Integer = legumes.Count' Exibe os valores obtidos ListBox1.Items.Add( "contador1=" & contador1)ListBox1.Items.Add( "contador2=" & contador2)ListBox1.Items.Add( "contador3=" & contador3)End Sub |
Se você necessitar copiar todo o conteúdo de um dicionário, para fazer isso basta declarar uma nova referência a um objeto Dictionary e usar o construtor Copy e passar no o dicionário que você deseja copiar como parâmetro.
A seguir temos um exemplo que copia um dicionário mamiferos para um novo objeto Dictionary , em seguida inclui mais uma chave no primeiro dicionário e a seguir lista os dois dicionários:
Private Sub dictionaryCopy()ListBox1.Items.Clear() Dim mamiferos As New Dictionary(Of String, Integer)() mamiferos.Add("cachoro", 1) mamiferos.Add("elefante", 9) mamiferos.Add("tigre", 10) ' Copia o Dicion rio para o segundo objeto Dim copy As New Dictionary(Of String, Integer)(mamiferos)' Altera o primeiro dicion rio (Isso nÆo causa altera‡äes na copia) mamiferos.Add( "tubarÆo", 4)' Exibe o primeiro dicion rio ListBox1.Items.Add( "--- Dictionary 1 ---") For Each par In mamiferosListBox1.Items.Add(par) Next' Exibe o seguind dicion rio ListBox1.Items.Add( "--- Dictionary 2 ---") For Each par In copyListBox1.Items.Add(par) NextEnd Sub |
As coleções são muito úteis na programação moderna e podem ajudar muito o desenvolvedor. Compreender o seu funcionamento correto é muito importante.
Pegue o projeto completo aqui : Dictonary.zip
Eu sei é apenas VB .NET, mas eu gosto...
referências:
José Carlos Macoratti