VB.NET - Usando Coleções


Se você procurar por coleções na plataforma .NET vai se deparar com o namespace System.Collections e uma relação de 10 classes diferentes que você terá que escolher para usar no seu projeto. Se você não estiver familiarizado com cada uma delas vai ser difícil você saber escolher qual classe se ajusta melhor ao caso específico do seu projeto.

Este artigo tem o objetivo de te dar um mão ,e , dar uma passada geral sobre coleções na plataforma .NET. Em diversos artigos eu já falei de muitas classes que vão aparecer aqui. Mas as informações estão dispersas e neste artigo vou procurar agrupar e fazer a referência ao artigo anterior quando for o caso.

Introdução

O que é uma coleção ?

Uma coleção é uma estrutura de dados ou um objeto que permite a você agrupar outros objetos.

As classes de coleções .NET oferece a você acesso a estrutura de dados pré-empacotados e a algoritmos para manipular essas estruturas.

Com coleções ao invés de ter que criar estruturas de dados via manipulação de referência  e alocação de memória você simplesmente usa estruturas de dados que já existem sem se importar como estas estruturas de dados foram implementadas.

Ao longo do artigo eu vou usar como exemplo uma classe chamada Cliente para ilustrar os exemplos em cada classe. Abaixo temos a nossa classe Cliente:

Pulic Class Cliente
       Private _nome As String
       Private _email As String

        Public Sub New(ByVal nome As String, ByVal email As String)
                         Me.Nome = nome
                         Me.Email = email
        End Sub

        Public Property Nome() As String
               Get
                     Return _nome
                End Get
                Set(ByVal Valor As String)
                         _nome = Valor
                End Set
       End Property

        Public Property Email() As String
               Get
                     Return _email
                End Get
                Set(ByVal Valor As String)
                         _email = Valor
                End Set
        End Property
End Class   

Na classe Cliente temos:

Dois atributos : _nome e _email do tipo String

Um construtor onde atribuímos o nome e o email ao cliente

Duas propriedades Get/Set onde podemos acessar os atributos Nome e Email da classe

 

Nota: Para criar a classe Clientes no VB.NET crie um novo projeto e no Menu Project selecione Add Class.

A seguir altere o nome da classe para Clientes.vb e insira o código ao lado.

 

A classe Array

Vou começar com a classe Array por que ela é uma das mais usadas e é também a mais básica. Na verdade , devido a suas limitações ,  talvez nem  possamos considerar uma coleção. Tanto é verdade que ela não se encontra no namespace System.Collections mas no  namespace System.

A coisa mais importante que você deve guardar sobre Arrays é que eles possuem um tamanho fixo. Assim ao declarar um Array você precisa definir o número de elementos(itens) que você deseja que o array contenha. Os arrays podem ter uma ou mais dimensões.

Outra coisa importante sobre arrays é que eles são fortemente tipados , ou seja, você pode guardar somente um tipo de objeto em um array.

Abaixo temos um exemplo onde estamos declarando um array de objetos Clientes que pode conter 2 objetos clientes. A seguir criamos duas instâncias de Cliente e colocamos no interior do array.

   Sub Main()
        'definimos um array de dois elementos (o índice começa com zero)
        Dim clientes(1) As Clientes
        'criamos duas instâncias do objeto clientes no array
        clientes(0) = New Clientes("Macoratti", "macoratti@yahoo.com")
        clientes(1) = New Clientes("Miriam", "miriam@bol.com.br")
        'acessamos os elementos do array  
        Console.WriteLine(clientes(0).Nome)
        Console.WriteLine(clientes(0).Email)
        Console.WriteLine(clientes(1).Nome)
        Console.WriteLine(clientes(1).Email)
       	'pausa  
        Console.ReadLine()

       End Sub

Quando você deve usar um Array ?   Quando você conhecer com antecedência quantos elementos sua coleção vai conter.

Se você precisar realizar operação com ordenação e busca considere o uso de outra classe da Coleção.

Para maiores detalhes sobre a classe Array veja o artigo : VB .NET - Arrays.

A classe ArrayList

A classe ArrayList é muito parecida com a classe array , as principais diferenças são :

- A classe ArrayList pode ter sua capacidade alterada dinamicamente
- A classe ArrayList pode armazenar mais de um tipo objeto (dizemos que a classe é tipada fracamente)

Abaixo o código instancia um arrayList e inclui dois objetos Clientes e a seguir exibe dados da classe Clientes:

   Sub Main()
        Dim cliente As ArrayList = New ArrayList
        cliente.Add(New Clientes("Macoratti", "macoratti@yahoo.com"))
        cliente.Add(New Clientes("Miriam", "miriam@yahoo.com"))
        Console.WriteLine(cliente(0).Nome)
        Console.WriteLine(cliente(0).Email)
        Console.WriteLine(cliente(1).Nome)
        Console.WriteLine(cliente(1).Email)
        Console.ReadLine()
    End Sub

A grande vantagem de um ArrayList é que você não precisa saber de antemão quantos itens ele vai conter.  Para criar um Array nestas condições usamos a função ToArray. Ao usar esta função você precisa usar o tipo de itens que você quer no ArrayList , como um parâmetro. Vejamos um exemplo:

  Sub Main()
        Dim cliente As New ArrayList
        Do
            'inclui objetos no arrayList
            Dim nome As String = InputBox("Nome do cliente")
            If nome = String.Empty Then
                Exit Do
            Else
                cliente.Add(New Clientes(nome, "111"))
            End If
        Loop
        'converte o ArrayList para um Array
        Dim clienteArray() = cliente.ToArray(GetType(Clientes))
        Console.ReadLine()
    End Sub

Para um exemplo prático usando ArrayList leia o artigo  : ASP .NET - Usando um ArrayList.

A classe Hashtable

A classe Hashtable é uma coleção onde você armazena objetos relacionados com uma chave de identificação. Para cada objeto que você incluir na hashtable você precisa informar um chave que identifica o objeto de forma única. Temos então que armazenar um par de valores : chave,objeto. Abaixo temos um exemplo de como usar armazenar objetos cliente em um Hashtable:

        Dim cliente As New Hashtable
        cliente.Add("A", New Clientes("Macoratti", "macoratti@yahoo.com"))
        cliente.Add("B", New Clientes("Jefferson", "jeff123@yahoo.com"))
        Console.ReadLine()

Note que ao incluir um objeto cliente informamos um parâmetro extra;  este parâmetro é a chave que no caso acima é uma string mas que pode ser de qualquer tipo.

O nome hashtable e conseqüência do hash (um valor numérico) que é gerado quando você inclui uma chave para identificar o objeto de forma única. O que fica armazenado na coleção não é a chave mas o hash calculado. Para recuperar o objeto você informa a sua chave:

CType(cliente("A"), Clientes).Nome = "Valor_Nome"

Você deve usar uma hashtable quando desejar acessar itens em sua coleção baseada em uma chave e não em um índice.

Para ver uma utilização prática de uma Hashtable leia o artigo : ASP.NET - Usando a classe HashTable.

A classe Queue

Você pode comparar a classe Queue com uma as pessoas que estão esperando em uma fila. A primeira pessoa que chega é a primeira a ser atendida ,  toda pessoa que chega é atendida na ordem de chegada. Este mecanismo é chamado FIFO : first in first out (primeiro a chegar primeiro a sair). Esta classe permite tratar coleções de objetos fracamente tipadas que são ordenadas pela ordem no qual eles são incluídos na coleção. O código abaixo mostra como incluímos e acessamos objetos em uma fila:

        Dim cliente As New Queue
        cliente.Enqueue(New Clientes("Macoratti", "macoratti@yahoo.com"))
        cliente.Enqueue(New Clientes("Jefferson", "jeff123@yahoo.com"))
        Dim primeiro As Clientes = cliente.Dequeue
        Dim segundo As Clientes = cliente.Dequeue
        Console.WriteLine(primeiro.Nome)
        Console.WriteLine(segundo.Nome)
        Console.ReadLine()

Observe que não usamos o método Add para incluir um objeto na fila mas sim o método Enqueue.

Para acessar um objeto na fila não usamos indice nem chave ; simplesmente recuperamos o primeiro da fila e depois o próximo e assim por diante. Usamos para isto o método Dequeue.

O método não só obtém o objeto cliente da fila mas também remove o objeto da coleção. Assim ao chamar o método novamente você pega o próximo objeto.

Você deve usar esta classe quando precisar tratar objetos que estão na ordem de sequência na coleção.

A classe Stack

A classe Stack funciona basicamente como a classe Queue com uma diferença :  O último objeto incluído na pilha é retornado primeiro . Imagine uma pilha de papéis , o primeiro que você pega da pilha foi o último que foi colocado nela. Este mecanismo é conhecido como LIFO : last in first out ( o último a entrar é o primeiro sair). Abaixo o código para preencher uma coleção Stack de objetos clientes:

     Dim cliente As New Stack
        cliente.Push(New Clientes("Macoratti", "macoratti@yahoo.com"))
        cliente.Push(New Clientes("Jefferson", "jeff123@yahoo.com"))
        Dim primeiro As Clientes = cliente.Pop
        Dim segundo As Clientes = cliente.Peek
        Console.WriteLine(primeiro.Nome)
        Console.WriteLine(segundo.Nome)
        Console.ReadLine()

O método Push é usado para incluir itens na pilha.

Para obter o último item incluído podemos usar o  método Pop ou o método Peek. A diferença é que o método Peek obtém o último objeto na pilha e o método Pop além de fazer isto remove o item da pilha.

Geralmente a utilização da classe Stack bem como da classe Queue fica restrita a uma possível implementação de um mecanismo LIFO ou FIFO mas é bom você saber que estas classe existem e como funcionam.

A classe SortedList

Podemos considerar a classe SortedList (Lista Ordenada) como uma combinação de um Array e de uma HashTable. Você pode acessar os itens em uma SortedList pelo índice (como um array) ou pela chave (como uma hashtable). Como o nome já diz uma SortedList é ordenada. Esta ordenação é baseada em uma chave única para cada elemento na coleção. A sequência do índice é baseada na sequencia de ordenação. Devido a ordenação esta classe tende a ser mais lenta que a classe Hashtable.

No código abaixo temos como criar uma nova SortedList e incluir dois objetos clientes. O método Add é o mesmo usado para a classe HashTable de forma que você tem que atribuir uma chave para cada objeto que incluir.

  Sub Main()
       Dim cliente As New SortedList
        cliente.Add("A", New Clientes("Macoratti", "macoratti@yahoo.com"))
        cliente.Add("B", New Clientes("Jefferson", "jeff123@yahoo.com"))
        Dim primeiro As Clientes = cliente("A")
         Dim segundo As Clientes = cliente.GetByIndex(1)
        Console.WriteLine(primeiro.Nome)
        Console.WriteLine(segundo.Nome)
        Console.ReadLine()
    End Sub

No código acima , a linha de código : Dim primeiro As Clientes = cliente("A")  obtém o cliente "Macoratti" usando a chave "A" atribuída ao objeto. Na linha   Dim segundo As Clientes = cliente.GetByIndex(1)  a obtemos o cliente "Jefferson" usando o índice 1. Como o primeiro índice tem valor igual a zero o valor 1 retorna o segundo elemento da Lista Ordenada.

Esta classe pode ser útil quando você precisar de uma lista ordenada ou precisar recuperar os objetos de uma coleção quer usando uma chave quer um índice.

Todas estas coleções analisadas são coleções ditas fracamente tipadas (com exceção da classe Array). Se você desejar uma coleção fortemente tipada deverá você mesmo criar sua coleção. Felizmente a plataforma .NET fornece classes abstratas que podem ser a base de sua construção. Vou falar rapidamente de duas em especial: CollectionBase e DictonaryBase.

A classe CollectionBase

A classe abstrata CollectionBase (você sabe o que significa o termo 'classe abstrata' ? ) fornece a classe base para uma coleção customizada fortemente tipada . Um a implementação básica seria :

Nota: Uma classe abstrata não pode ser instanciada (não podemos chamar seus construtores) e é utilizada quando você deseja fornecer uma interface comum a diversos membros de uma hierarquia de classes. Os métodos declarados na classe abstrata serão implementados em suas subclasses usando polimorfismo.(Uma classe abstrata pode definir o protocolo para uma operação sem fornecer o código correspondente.)

Para maiores detalhes leia o artigo : VB .NET - Primeiros passos - Conceitos - VI.

Public Class ClientesColecao
    Inherits CollectionBase
    Public Sub New()
        MyBase.new()
    End Sub
    Public Sub Add(ByVal cliente As Clientes)
        MyBase.InnerList.Add(cliente)
    End Sub

    Default Public Property Item(ByVal index As Integer) As Clientes
        Get
            Return MyBase.InnerList(index)
        End Get
        Set(ByVal Value As Clientes)
            MyBase.InnerList(index) = Value
        End Set
    End Property

End Class

No código acima a classe ClientesColecao herda da classe Pai CollectionBase . Incluimos um método Add para incluir Clientes e uma propriedade Item para acessar os itens na coleção. Esta propriedade retorna um objeto do tipo Cliente pois , como dissemos , a classe é fortemente tipada . Com isto não é necessário usar Cast para retornar os valores da coleção.

Perceba que a classe CollectionBase é construída sobre um ArrayList que é armazenado internamente.

Para terminar falta falar da classe DictionaryBase. Esta classe usa internamente uma HashTale para armazenar itens da coleção e como a classe CollectionBase é uma classe abstrata que serve de base para você implementar sua própria classe.

E acabei o assunto coleções deste artigo.

Até o próximo....


Veja os Destaques e novidades do SUPER DVD VB (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Veja mais sistemas completos para a plataforma .NET no Super DVD .NET , confira...

Quer aprender C# ??

Chegou o Super DVD C# com exclusivo material de suporte e vídeo aulas com curso básico sobre C#
 

   Gostou ?   Compartilhe no Facebook    Compartilhe no Twitter

Referências:


José Carlos Macoratti