VB .NET - Realizando operações com List(of T)
Hoje vou mostrar como como realizar operações com coleção fortemente tipadas de objetos do tipo List(Of T).
A coleção genérica List(Of T) representa uma lista fortemente tipada de objetos que podem ser acessados através de um índice e fornece métodos para procurar(Search), ordenar(Sort) e manipular a lista.
Nota: O parâmetro (Of T) na declaração da lista é obrigatório e indica qual o tipo de dados que poderá ser incluído na coleção. ( A versão não genérica desta coleção e a classe ArrayList )
Neste artigo você vai aprender a :
Requisitos:
Objetivos
Criar e realizar as principais operações com uma coleção genérica List(Of T).
Criando o projeto no Visual Studio 2012 Express for desktop
Abra o Visual Studio 2012 Express for desktop e clique em New Project;
A seguir selecione o template Windows Forms Application, informe o nome OperacoesCom_List e clique em OK;
A seguir vamos incluir uma nova classe no projeto que representará o no nosso domínio e a partir da qual iremos criar a nossa coleção genérica do tipo desta classe.
No menu PROJECT clique em Add Class;
A seguir selecione o template Class, informe o nome Pessoa.vb e clique no botão Add e a seguir defina o seguinte código nesta classe:
Public Class Pessoa Public Property Id() As Integer Public Property Nome As String Public Property Sobrenome As String Public Property Idade() As Short Public Property Sexo As Nullable(Of Char) Public Sub New() End Sub Public Sub New(ByVal _id As Integer, ByVal _nome As String, ByVal _sobrenome As String, ByVal _idade As Short, ByVal _sexo As Char) Me.Id = _Id Me.Nome = _nome Me.Sobrenome = _sobrenome Me.Idade = _idade Me.Sexo = _sexo End Sub End Class |
A classe Pessoa define 5 propriedades e dois construtores sendo que um esta vazio e outro permite inicializar os valores das propriedades.
A seguir vamos incluir a partir da Toolbox os seguintes controles no formulário form1.vb:
Disponha os controles conforme o leiaute abaixo:
No início do formulário vamos declarar a variável listaPessoas ue será usada no projeto:
Dim listaPessoas As List(Of Pessoa)
Criando as rotinas de suporte às operações
Para criar uma lista de objetos Pessoa vamos usar a classe Pessoa e definir o no formulário form1.vb a seguinte rotina:
Private Sub criarLista() listaPessoas = New List(Of Pessoa)() listaPessoas.Add(New Pessoa(1, "Jose Carlos", "Macoratti", 45, "M"c)) listaPessoas.Add(New Pessoa(2, "Jefferson", "Jacobs", 19, "M"c)) listaPessoas.Add(New Pessoa(3, "Miriam", "Agata", 25, "F"c)) listaPessoas.Add(New Pessoa(4, "Janice", "Limeira", 18, "F"c)) listaPessoas.Add(New Pessoa(5, "Lena", "Bianca", 33, "F"c)) listaPessoas.Add(New Pessoa(6, "Susana", "Vieira", 45, "F"c)) listaPessoas.Add(New Pessoa(7, "Jonas", "Buarque", 38, "M"c)) listaPessoas.Add(New Pessoa(8, "Jane", "Hooks", 32, "F"c)) listaPessoas.Add(New Pessoa(9, "Roberto", "Barros", 31, "M"c)) listaPessoas.Add(New Pessoa(10, "Carlos", "Fogaça", 25, "F"c)) listaPessoas.Add(New Pessoa(11, "Gina", "Pereira", 27, "F"c)) listaPessoas.Add(New Pessoa(12, "Joel", "Vieira", 33, "M"c)) listaPessoas.Add(New Pessoa(13, "George", "Douglas", 55, "M"c)) listaPessoas.Add(New Pessoa(14, "Ricardo", "Benitez", 22, "M"c)) listaPessoas.Add(New Pessoa(15, "Maria", "Silveira", 39, "F"c)) End Sub |
Vamos criar também uma rotina que será usada para exibir o resultado das operações no controle ListBox (lstbResultado) conforme o código a seguir:
Private Sub ExibirResultado(ByVal lista As List(Of Pessoa), ByVal info As String) lstbResultado.Items.Add(info) lstbResultado.Items.Add(vbCrLf) lstbResultado.Items.Add("ID" & vbTab & "Nome " & vbTab & "Sobrenome" & vbTab & "Idade" & vbTab & "Sexo") lstbResultado.Items.Add(vbCrLf) For Each p As Pessoa In lista lstbResultado.Items.Add(p.Id & vbTab & p.Nome & vbTab & p.Sobrenome & vbTab & p.Idade & vbTab & p.Sexo) Next lstbResultado.Items.Add(vbCrLf) End Sub |
A rotina ExibirResultado() irá receber a lista genérica e uma texto que deverá ser exibido no controle ListBox.
1- Criando a lista genérica
Para criar a lista genérica de objetos Pessoa vamos incluir o código abaixo no evento Click do botão - Criar Lista de Pessoas :
Private Sub btnCriarLista_Click(sender As Object, e As EventArgs) Handles btnCriarLista.Click Try criarLista() ExibirResultado(listaPessoas, "Lista de Pessoas - listaPessoas - criada com sucesso") Catch ex As Exception MessageBox.Show("Erro : " + ex.Message) End Try End Sub |
O código cria uma lista genérica listaPessoas() usando a rotina CriarLista() e exibe a lista no ListBox na rotina ExibirResultado passando a lista e a informação desejada.
O resultado é visto abaixo:
2- Percorrendo a lista genérica
Para percorrer a lista chamamos a rotina ExibiResultado() no evento Click do botão - Percorrer Lista:
Private Sub btnPercorreLista_Click(sender As Object, e As EventArgs) Handles btnPercorreLista.Click Try ExibirResultado(listaPessoas, "Percorrendo a Lista de Pessoas - listaPessoas - com sucesso") Catch ex As Exception MessageBox.Show("Erro : " + ex.Message) End Try End Sub |
A lista é percorrida usando um laço For Each na lista genérica:
..... For Each p As Pessoa In lista lstbResultado.Items.Add(p.Id & vbTab & p.Nome & vbTab & p.Sobrenome & vbTab & p.Idade & vbTab & p.Sexo) Next ..... |
3- Filtrando a Lista usando uma condição única
No evento Click do botão - Filtrar Lista - Condição única - temos o código abaixo:
Private Sub btnFiltrarListaCondUnica_Click(sender As Object, e As EventArgs) Handles btnFiltrarListaCondUnica.Click Try Dim listaFiltrada As List(Of Pessoa) = listaPessoas.FindAll(Function(p As Pessoa) p.Idade > 35) ExibirResultado(listaFiltrada, "3. --- Filtrando List(Of T) com uma condição (Idade > 35)") Catch ex As Exception MessageBox.Show("Erro : " + ex.Message) End Try End Sub |
Estamos filtrando a lista usando o seguinte código:
Dim listaFiltrada As List(Of Pessoa) = listaPessoas.FindAll(Function(p As Pessoa) p.Idade > 35)
Onde temos:
listaPessoas.FindAll(Function(p As Pessoa) p.Idade > 35)
O método FindAll() - Recupera todos os elementos que coincidem com as condições definidas pelo predicado especificado, no caso uma consulta LINQ usando uma expressão lambda.
Function(p As Pessoa) p.Idade > 35 - é uma expressão lambda que estamos usando para realizar a consulta LINQ para retornar os objetos Pessoa com Idade > 35
As expressões lambdas são funções que podem conter expressões e declarações que são usadas para criar delegates e árvores de expressões onde o tipo das variáveis não precisam ser declarados visto que elas usam métodos anônimos.
O resultado é o seguinte:
4- Filtrando a Lista usando mais de uma condição
Podemos usar mais de uma condição para filtrar uma lista genérica. No evento Click do botão de comando - Filtrar Lista - Múltiplas Condições - temos o código que faz isso:
Private Sub btnFiltrarListaMultCond_Click(sender As Object, e As EventArgs) Handles btnFiltrarListaMultCond.Click Try Dim listaFiltrada As List(Of Pessoa) = listaPessoas.FindAll(Function(p As Pessoa) p.Idade > 35 And p.Sexo = "F"c) ExibirResultado(listaFiltrada, "4. --- Filtrando List(Of T) com duas condições (Idade > 35 e Sexo Feminino)") Catch ex As Exception MessageBox.Show("Erro : " + ex.Message) End Try End Sub |
Estamos filtrando a lista usando o seguinte código:
Dim listaFiltrada As List(Of Pessoa) = listaPessoas.FindAll(Function(p As Pessoa) p.Idade > 35 And p.Sexo = "F"c )
Onde temos:
listaPessoas.FindAll(Function(p As Pessoa) p.Idade > 35 And p.Sexo = "F"c)
O método FindAll() - Recupera todos os elementos que coincidem com as condições definidas pelo predicado especificado, no caso uma consulta LINQ usando uma expressão lambda.
Function(p As Pessoa) p.Idade > 35 And p.Sexo = "F"c - é uma expressão lambda que estamos usando para realizar a consulta LINQ para retornar os objetos Pessoa com Idade > 35 e Sexo Feminino.
O resultado é obtido é visto abaixo:
5- Ordenando uma lista genérica
Para ordernar uma lista genérica usamos o código a seguir no evento Click do botão - Ordernar Lista:
Private Sub btnOrdenarLista_Click(sender As Object, e As EventArgs) Handles btnOrdenarLista.Click Dim listaOrdenadaPorNome As List(Of Pessoa) = listaPessoas listaOrdenadaPorNome.Sort(Function(p1 As Pessoa, p2 As Pessoa) p1.Nome.CompareTo(p2.Nome)) ExibirResultado(listaOrdenadaPorNome, "5. --- Ordenar List(Of T) (Sort on Nome) ---") End Sub |
O código define uma outra lista chamada listaOrdernadaPorNome com o mesmo conteúdo da nossa lista listaPessoas e aplica o método Sort na lista listaOrdernadaPorNome.
O método Sort classifica os elementos em todo o List (Of T) usando o comparador padrão. Por este motivo criamos outra lista idêntica a que já tínhamos no início.
Este método usa o comparador padrão Comparer(Of T) para determinar a ordem dos elementos da lista. A propriedade Comparer(Of T).Default verifica se o tipo T implementa a interface genérica IComparable(Of T) e usa essa implementação, se disponível. Se não ele verifica se o tipo T implementa a interface IComparable. Se o tipo T não implementa qualquer interface, Comparer(Of T).Default lança um InvalidOperationException.
Este método utiliza Array.Sort, que usa o algoritmo QuickSort. Esta implementação executa uma classificação instável, ou seja, se dois elementos são iguais, sua ordem não será preservada.(Uma ordenação estável preserva a ordem dos elementos que são iguais).
Abaixo vemos o resultado da ordenação:
6- Ordenando uma lista genérica - 2
Para ordenar uma lista genérica usamos o código a seguir no evento Click do botão - Ordernar Lista (2) :
Private Sub btnOrdenarLista2_Click(sender As Object, e As EventArgs) Handles btnOrdenarLista2.Click Dim listaOrdenadaPorSobreNome As List(Of Pessoa) = listaPessoas listaOrdenadaPorSobreNome.Sort(Function(p1 As Pessoa, p2 As Pessoa) p2.Sobrenome.CompareTo(p1.Sobrenome)) ExibirResultado(listaOrdenadaPorSobreNome, "6. --- Ordenar List(Of T) (Sort on Nome) ---") End Sub |
O código define uma outra lista chamada listaOrdernadaPorSobreNome com o mesmo conteúdo da nossa lista listaPessoas e aplica o método Sort na lista listaOrdernadaPorSobreNome.
O método Sort classifica os elementos em todo o List(Of T) usando o comparador padrão. Por este motivo criamos outra lista idêntica a que já tínhamos no início.
O resultado é mostrado na figura abaixo:
7- Adicionando novos objetos na lista genérica
No evento Click do botão Adicionar Objetos na lista temos o código que permite incluir novos objetos na lista genérica do tipo Pessoa:
Private Sub btnAdicionarNaLista_Click(sender As Object, e As EventArgs) Handles btnAdicionarNaLista.Click Dim novaLista As List(Of Pessoa) = New List(Of Pessoa)() novaLista.Add(New Pessoa(16, "Teste", "Testolino", 29, "M"c)) novaLista.Add(New Pessoa(17, "Testa", "Testolina", 32, "F"c)) listaPessoas.AddRange(novaLista) ExibirResultado(listaPessoas, "7. --- Incluir novo objeto na lista List(Of T) a uma lista existente List() ---") End Sub |
Definimos uma nova lista do mesmo tipo da nossa lista original, criamos novos objetos Pessoa e usamos o método AddRange para incluir os objetos na lista.
O método AddRange adiciona os elementos da coleção especificada ao fim da List(Of T) sendo que a ordem da coleção é preservada na lista.
Se o novo contador (Count) (o contador (Count) atual mais o tamanho da coleção) for maior do que a capacidade da lista (Capacity), a capacidade da List(Of T) será aumentada, realocando automaticamente a matriz interna para acomodar os elementos novos, e os elementos existentes são copiados para a nova matriz antes dos novos elementos serem adicionados.
A seguir vemos os novos elementos adicionados exibidos:
8- Removendo objetos da lista genérica
Para remover um objeto da lista usamos o método RemoveAll usando um critério que deverá ser verificado e atendido. No evento Click do botão - Remover itens da lista - temos o código que faz essa operação:
Private Sub btnRemoverItemLista_Click(sender As Object, e As EventArgs) Handles btnRemoverItemLista.Click Dim removerLista As List(Of Pessoa) = listaPessoas removerLista.RemoveAll(Function(p As Pessoa) p.Sexo = "M"c) ExibirResultado(removerLista, "8. --- Remove mais de um item da lista ListOf T) baseado em uma condição ---") End Sub |
O método RemoveAll remove todos os elementos que coincidem com as condições definidas pelo predicado especificado.
Public Function RemoveAll (criterio As Predicate(Of T)) As Integer
O Predicate(Of T) é um delegado para um método que retorna true se o objeto passado para ele coincide com as condições definidas no delegado. Os elementos List(Of T) atual são individualmente passados para o delegado Predicate(Of T) e os elementos que atendam às condições são removidos da List(Of T).
Esse método realiza uma pesquisa linear; Portanto, esse método é uma operação O(n) onde n é Count.
O resultado onde removemos todas as pessoas do sexo masculino da lista é exibido abaixo:
9 - Criando uma lista genérica somente-leitura
No botão - Criar Lista Somente-Leitura - temos o código onde criamos uma lista que não poderá ser modificada diretamente.
Private Sub btnCriarListaSomenteLeitura_Click(sender As Object, e As EventArgs) Handles btnCriarListaSomenteLeitura.Click Dim pessoaSomenteLeitura As IList(Of Pessoa) = listaPessoas lstbResultado.Items.Add("Antes - Esta lista é somente-leitura ? True ou False : " & pessoaSomenteLeitura.IsReadOnly) pessoaSomenteLeitura = listaPessoas.AsReadOnly() lstbResultado.Items.Add("Depois - Esta lista é somente-leitura ? True ou False : " & pessoaSomenteLeitura.IsReadOnly) End Sub |
O método AsReadOnly retorna um invólucro IList(Of T) somente leitura para a coleção atual. Para evitar quaisquer modificações na List(Of T), é exposta uma List(Of T) através de um invólucro.
Uma coleção que é somente leitura é simplesmente uma coleção com um invólucro que impede a modificação da coleção e, portanto, se forem feitas alterações na coleção subjacente, a coleção somente leitura reflete essas mudanças.
O código abaixo mostra o resultado após executarmos a operação com : listaPessoas.AsReadOnly()
Pegue o projeto completo aqui: OperacoesCom_List.zip
Mat 8:24 E eis que se levantou no mar tão grande tempestade que o barco era coberto pelas ondas; ele, porém, estava dormindo.
Mat 8:25 Os discípulos, pois, aproximando-se, o despertaram, dizendo: Salva-nos, Senhor, que estamos perecendo.
Mat 8:26 Ele lhes respondeu: Por que temeis, homens de pouca fé? Então, levantando-se repreendeu os ventos e o mar, e seguiu-se grande bonança.
Mat 8:27 E aqueles homens se maravilharam, dizendo: Que homem é este, que até os ventos e o mar lhe obedecem? (Jesus)
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#