Olá! Meu nome é Mikael, sou instrutor na Alura, e quero dar as boas-vindas ao curso de Praticando com Dart!.
Audiodescrição: Mikael se descreve como um homem de pele preta e cabelo crespo. Veste uma camiseta lisa na cor preta e está em um ambiente de cor azul.
Neste curso, exploraremos as collections no Dart, abordando o funcionamento de listas, sets e mapas. Utilizaremos o Dart Pad como ambiente de desenvolvimento.
Para começar, escolha o navegador de sua preferência e acesse dartpad.dev. Esse será o ambiente onde desenvolveremos e executaremos o programa ao longo do curso.
Ao acessar o DartPad, você verá um código inicial que será descartado, pois construiremos nosso programa do zero. A proposta é criar uma simulação de envio de e-mails.
enviarEmail()
Iniciaremos com a criação de uma função responsável por simular o envio de e-mails. Essa função será do tipo void
, pois não retornará nenhum valor, e será chamada enviarEmail()
. Ela receberá um parâmetro do tipo String
, representando o e-mail a ser enviado. Em seguida, exibirá uma mensagem no terminal indicando que uma mensagem foi enviada para o e-mail informado.
void enviarEmail(String email){
print('mensagem enviada para: $email');
}
main()
Com a função enviarEmail()
criada, o próximo passo é desenvolver a função main()
, que será responsável por executar nosso código. A função main()
também será do tipo void
e não receberá parâmetros.
Dentro dela, declararemos duas variáveis do tipo String
:
joaoEmail
, que armazenará o valor joao@gmail.com
;mariaEmail
, que armazenará o valor maria@gmail.com
.Em seguida, utilizaremos a função enviarEmail()
para enviar mensagens para esses endereços de e-mail, passando joaoEmail
e mariaEmail
como parâmetros.
void enviarEmail(String email){
print('mensagem enviada para: $email');
}
void main(){
String joaoEmail = 'joao@gmail.com';
String mariaEmail ='maria@gmail.com';
enviarEmail(joaoEmail);
enviarEmail(mariaEmail);
}
Após criar as variáveis e utilizar a função de envio de e-mail, podemos testar o código clicando no botão "Run". Ao executar, serão exibidas as mensagens:
mensagem enviada para: joao@gmail.com
mensagem enviada para: maria@gmail.com
Isso indica que a função está funcionando corretamente.
No entanto, se precisarmos enviar mensagens para uma grande quantidade de e-mails, como cem ou mil, o uso de variáveis individuais não será eficiente. Criar mil variáveis e chamar a função de envio de e-mail manualmente para cada uma delas geraria muito retrabalho.
É nesse cenário que as collections se tornam indispensáveis, pois oferecem uma estrutura eficiente para manipular grandes quantidades de dados de forma organizada e prática.
Vamos agora implementar uma lista no programa de envio de e-mails. Para isso, criaremos uma lista utilizando a classe List
, especificando que ela armazenará valores do tipo String
. Nomearemos essa lista como listaEmails
, que inicialmente estará vazia.
void enviarEmail(String email){
print('mensagem enviada para: $email');
}
void main(){
String joaoEmail = 'joao@gmail.com';
String mariaEmail ='maria@gmail.com';
enviarEmail(joaoEmail);
enviarEmail(mariaEmail);
List<String> listaEmails = [];
}
Para adicionar valores à lista, utilizaremos vírgulas para separar os elementos. Nesse caso, incluiremos os e-mails joao@gmail.com
e maria@gmail.com
na listaEmails
.
void enviarEmail(String email){
print('mensagem enviada para: $email');
}
void main(){
String joaoEmail = 'joao@gmail.com';
String mariaEmail ='maria@gmail.com';
enviarEmail(joaoEmail);
enviarEmail(mariaEmail);
List<String> listaEmails = ['joao@gmail.com', 'maria@gmail.com'];
}
Com os e-mails armazenados na lista, podemos eliminar as variáveis individuais que usávamos anteriormente.
void enviarEmail(String email){
print('mensagem enviada para: $email');
}
void main(){
List<String> listaEmails = ['joao@gmail.com', 'maria@gmail.com'];
}
Para acessar os elementos da lista, utilizaremos índices. Para exibir joao@gmail.com
, que está na primeira posição, utilizaremos a função print
passando listaEmails[]
com o índice 0 entre colchetes.
Quando o elemento está na primeira posição da lista, seu índice é 0. Quando está na segunda posição, o índice é 1. Na terceira, é 2. Na quarta, é 3, e assim sucessivamente.
void enviarEmail(String email){
print('mensagem enviada para: $email');
}
void main(){
List<String> listaEmails = ['joao@gmail.com', 'maria@gmail.com'];
print(listaEmails[0]);
}
Ao executar, obtemos joao@gmail.com
. Para exibir maria@gmail.com
basta seguir o mesmo processo utilizando o índice 1.
void enviarEmail(String email){
print('mensagem enviada para: $email');
}
void main(){
List<String> listaEmails = ['joao@gmail.com', 'maria@gmail.com'];
print(listaEmails[1]);
}
for
No entanto, ainda precisamos de uma forma eficiente de enviar e-mails para todos os elementos da lista sem chamar a função manualmente para cada posição. Para isso, utilizaremos um laço for
, que percorrerá a listaEmails
.
O laço funcionará da seguinte forma: para cada String email
presente em listaEmails
, chamaremos o método print
. Dessa maneira, todos os e-mails da lista serão impressos.
void enviarEmail(String email){
print('mensagem enviada para: $email');
}
void main(){
List<String> listaEmails = ['joao@gmail.com', 'maria@gmail.com'];
for(String email in listaEmails){
print(email);
}
}
Após implementar essa solução, podemos testar o código clicando em "Run". Se tudo estiver correto, veremos os emails joao@gmail.com
e maria@gmail.com
no terminal.
Nosso objetivo não é apenas exibir os e-mails, mas também enviar uma mensagem para cada um deles. Para isso, substituiremos a função print
pela função enviarEmail
.
void enviarEmail(String email){
print('mensagem enviada para: $email');
}
void main(){
List<String> listaEmails = ['joao@gmail.com', 'maria@gmail.com'];
for(String email in listaEmails){
enviarEmail(email);
}
}
Ao executar o código, obtemos o retorno de mensagem enviada para cada um dos emails:
mensagem enviada para: joao@gmail.com
mensagem enviada para: maria@gmail.com
Além dos valores iniciais que declaramos na lista, como os e-mails de João e Maria, queremos adicionar outros valores, como o e-mail do Enzo. Para adicionar um novo valor, utilizamos os métodos da lista.
Métodos são funcionalidades que facilitam a execução de operações com nossas collections. Eles estão disponíveis tanto para listas quanto para sets e mapas, que vamos explorar mais adiante.
No caso das listas, para adicionar um elemento, usamos o método add
. Ou seja, para adicionar o e-mail do Enzo, basta escrever listaEmails.add()
, e dentro dos parênteses, passar o valor que queremos adicionar, enzo@gmail.com
.
void enviarEmail(String email){
print('mensagem enviada para: $email');
}
void main(){
List<String> listaEmails = ['joao@gmail.com', 'maria@gmail.com'];
listaEmails.add('enzo@gmail.com');
for(String email in listaEmails){
enviarEmail(email);
}
}
Ao executar o código, a mensagem também é enviada para o novo email adicionado:
mensagem enviada para: joao@gmail.com
mensagem enviada para: maria@gmail.com
mensagem enviada para: enzo@gmail.com
contains
É possível que, por um erro de digitação, um email já existente seja adicionado novamente à lista, causando duplicidade. Para evitar esse problema, podemos utilizar o método contains
antes de adicionar um novo e-mail.
Em uma condicional if
utilizaremos esse método para verificar se o e-mail já está presente na lista. Se não estiver, utilizamos o método add
para incluí-lo.
void enviarEmail(String email){
print('mensagem enviada para: $email');
}
void main(){
List<String> listaEmails = ['joao@gmail.com', 'maria@gmail.com'];
listaEmails.add('enzo@gmail.com');
if(listaEmails.contains('enzo@gmail.com')==false){
listaEmails.add('enzo@gmail.com');
}
for(String email in listaEmails){
enviarEmail(email);
}
}
Ao executar, o código funciona corretamente e obtemos o seguinte retorno:
mensagem enviada para: joao@gmail.com
mensagem enviada para: maria@gmail.com
mensagem enviada para: enzo@gmail.com
Embora o contains
seja eficiente em listas pequenas, ele percorre toda a lista para verificar a existência do e-mail. Em listas grandes, isso pode afetar o desempenho. Nesse caso, uma solução mais eficiente é utilizar um set.
A declaração de um set é semelhante à de uma lista, mas utilizamos Set
em vez de List
. No nosso caso, especificaremos que o set armazenará valores do tipo String
e o nomearemos como setEmails
. Inicializamos o set utilizando chaves {}
.
Antes de continuar, vamos comentar parte do código anterior e focar apenas na utilização do set.
void enviarEmail(String email){
print('mensagem enviada para: $email');
}
void main(){
// List<String> listaEmails = ['joao@gmail.com', 'maria@gmail.com'];
// listaEmails.add('enzo@gmail.com');
// if(listaEmails.contains('enzo@gmail.com')==false){
// listaEmails.add('enzo@gmail.com');
// }
// for(String email in listaEmails){
// enviarEmail(email);
// }
Set<String> setEmails = {};
}
Para inicializar nosso set, seguimos o mesmo processo que usamos com a lista: passamos os elementos separados por vírgula.
void enviarEmail(String email) {
print('mensagem enviada para: $email');
}
void main() {
// List<String> listaEmails = ['joao@gmail.com', 'maria@gmail.com'];
// listaEmails.add('enzo@gmail.com');
// if(listaEmails.contains('enzo@gmail.com')==false){
// listaEmails.add('enzo@gmail.com');
// }
// for(String email in listaEmails){
// enviarEmail(email);
// }
Set<String> setEmails = {'joao@gmail.com', 'maria@gmail.com'};
}
Set
Com isso, podemos começar a utilizar o set e testar algumas operações. A primeira coisa que vamos fazer é percorrer os e-mails armazenados e imprimi-los. Para isso, usaremos novamente o laço de repetição for
. A sintaxe será:
for(String email in setEmails) {
print(email);
}
Código completo:
void enviarEmail(String email) {
print('mensagem enviada para: $email');
}
void main() {
// List<String> listaEmails = ['joao@gmail.com', 'maria@gmail.com'];
// listaEmails.add('enzo@gmail.com');
// if(listaEmails.contains('enzo@gmail.com')==false){
// listaEmails.add('enzo@gmail.com');
// }
// for(String email in listaEmails){
// enviarEmail(email);
// }
Set<String> setEmails = {'joao@gmail.com', 'maria@gmail.com'};
for (String email in setEmails) {
print(email);
}
}
Ao executar, obtemos os emails joao@gmail.com
e maria@gmail.com
.
Set
Os elementos são adicionados ao set da mesma forma que na lista, com o método add
. Portanto, adicionaremos o email enzo@gmail.com
:
void enviarEmail(String email) {
print('mensagem enviada para: $email');
}
void main() {
// List<String> listaEmails = ['joao@gmail.com', 'maria@gmail.com'];
// listaEmails.add('enzo@gmail.com');
// if(listaEmails.contains('enzo@gmail.com')==false){
// listaEmails.add('enzo@gmail.com');
// }
// for(String email in listaEmails){
// enviarEmail(email);
// }
Set<String> setEmails = {'joao@gmail.com', 'maria@gmail.com'};
setEmails.add('enzo@gmail.com');
for (String email in setEmails) {
print(email);
}
}
Ao executar, obtemos os 3 e-mails: joao@gmail.com
, maria@gmail.com
e enzo@gmail.com
.
Set
Em seguida, faremos um teste para verificar o comportamento do set ao tentarmos adicionar o mesmo e-mail duas vezes.
void enviarEmail(String email) {
print('mensagem enviada para: $email');
}
void main() {
// List<String> listaEmails = ['joao@gmail.com', 'maria@gmail.com'];
// listaEmails.add('enzo@gmail.com');
// if(listaEmails.contains('enzo@gmail.com')==false){
// listaEmails.add('enzo@gmail.com');
// }
// for(String email in listaEmails){
// enviarEmail(email);
// }
Set<String> setEmails = {'joao@gmail.com', 'maria@gmail.com'};
setEmails.add('enzo@gmail.com');
setEmails.add('enzo@gmail.com');
for (String email in setEmails) {
print(email);
}
}
Ao executar, obtemos os 3 e-mails: joao@gmail.com
, maria@gmail.com
e enzo@gmail.com
.
Em uma lista, isso resultaria em duplicação, mas no set, o e-mail não será duplicado. Isso ocorre porque o set evita automaticamente elementos repetidos, o que o torna ideal para situações em que a unicidade dos dados é essencial.
Set
Para verificar se um e-mail específico está presente no set, utilizamos o método contains
. Por exemplo, ao verificar a presença do e-mail do Enzo, a função retornará true
se ele estiver no set. Caso contrário, exibiremos uma mensagem informando que o e-mail não foi encontrado.
Antes de testar o código, removeremos o laço de repetição para evitar duplicidades na saída.
void enviarEmail(String email) {
print('mensagem enviada para: $email');
}
void main() {
// List<String> listaEmails = ['joao@gmail.com', 'maria@gmail.com'];
// listaEmails.add('enzo@gmail.com');
// if(listaEmails.contains('enzo@gmail.com')==false){
// listaEmails.add('enzo@gmail.com');
// }
// for(String email in listaEmails){
// enviarEmail(email);
// }
Set<String> setEmails = {'joao@gmail.com', 'maria@gmail.com'};
setEmails.add('enzo@gmail.com');
setEmails.add('enzo@gmail.com');
if (setEmails.contains('enzo@gmail.com') == true) {
print('email de enzo dentro do set');
} else {
print('não está dentro do set');
}
}
Ao executar, confirmamos que o e-mail do Enzo está presente no set. Se alterarmos a verificação para enzod@gmail.com
, o programa exibirá uma mensagem informando que o e-mail não está no set.
void enviarEmail(String email) {
print('mensagem enviada para: $email');
}
void main() {
// List<String> listaEmails = ['joao@gmail.com', 'maria@gmail.com'];
// listaEmails.add('enzo@gmail.com');
// if(listaEmails.contains('enzo@gmail.com')==false){
// listaEmails.add('enzo@gmail.com');
// }
// for(String email in listaEmails){
// enviarEmail(email);
// }
Set<String> setEmails = {'joao@gmail.com', 'maria@gmail.com'};
setEmails.add('enzo@gmail.com');
setEmails.add('enzo@gmail.com');
if (setEmails.contains('enzod@gmail.com') == true) {
print('email de enzo dentro do set');
} else {
print('não está dentro do set');
}
}
Esse comportamento destaca a importância de atenção aos detalhes na escrita dos e-mails.
Além do método add
e da prevenção de duplicidade, o set oferece vantagens de desempenho em operações de busca, pois não precisa percorrer todos os elementos como acontece nas listas.
Map
Agora, vamos explorar o uso de maps.
Suponha que, além dos e-mails, queremos associar um nome a cada pessoa. Para isso, utilizamos um map, onde cada chave representa um nome e cada valor armazena o e-mail correspondente.
Vamos comentar o código utilizado e criar um Map
chamado pessoasEmails
, especificando que tanto as chaves quanto os valores serão do tipo String
. Inicializamos o map com pares de chave e valor, como joao
associado a joao@gmail.com
. Faremos o mesmo para a Maria, associando o nome ao e-mail maria@gmail.com
:
void enviarEmail(String email) {
print('mensagem enviada para: $email');
}
void main() {
// código comentado
Map<String, String> pessoasEmails = {
'joao': 'joao@gmail.com',
'maria': 'maria@gmail.com',
};
}
Map
Para acessar um valor no map, utilizamos a chave correspondente. Por exemplo, ao fornecer a chave joao
, o map retorna o valor associado, que é joao@gmail.com
.
void enviarEmail(String email) {
print('mensagem enviada para: $email');
}
void main() {
// código comentado
Map<String, String> pessoasEmails = {
'joao': 'joao@gmail.com',
'maria': 'maria@gmail.com',
};
print(pessoasEmails['joao']);
}
Map
Podemos adicionar um novo par ao map usando a sintaxe de colchetes. Por exemplo, para associar o e-mail de Enzo ao seu nome, utilizamos pessoasEmails['enzo'] = 'enzo@gmail.com';
. Em seguida, podemos imprimir pessoasEmails['enzo']
para obter o e-mail associado:
void enviarEmail(String email) {
print('mensagem enviada para: $email');
}
void main() {
// código comentado
Map<String, String> pessoasEmails = {
'joao': 'joao@gmail.com',
'maria': 'maria@gmail.com',
};
pessoasEmails['enzo'] = 'enzo@gmail.com';
print(pessoasEmails['enzo']);
}
Outra funcionalidade útil do map é verificar se uma chave existe, utilizando o método containsKey
. Isso é especialmente útil para evitar substituições acidentais de valores. Por exemplo, ao utilizar print(pessoasEmails.containsKey('enzo'))
, obteremos true
, indicando que a chave existe.
void enviarEmail(String email) {
print('mensagem enviada para: $email');
}
void main() {
// código comentado
Map<String, String> pessoasEmails = {
'joao': 'joao@gmail.com',
'maria': 'maria@gmail.com',
};
pessoasEmails['enzo'] = 'enzo@gmail.com';
print(pessoasEmails.containsKey('enzo'));
}
Se fizéssemos o mesmo utilizando a chave mikael
, obteríamos false
, pois essa chave não existe no map.
Para finalizar, vamos enviar uma mensagem para cada e-mail presente no nosso mapa. Mas, antes de fazer isso, é importante observar que não podemos utilizar o mesmo laço for
tradicional que usávamos para listas e sets. Isso acontece porque o pessoasEmails
não armazena apenas strings, mas sim pares de chave e valor. Portanto, não podemos usar a mesma abordagem que usamos anteriormente.
A solução é utilizar um método específico para mapas, o values
, que nos permite acessar os valores armazenados no mapa. Por exemplo, se quisermos obter apenas os e-mails, podemos usar o comando de impressão print
aplicado à pessoasEmails.values
:
void enviarEmail(String email) {
print('mensagem enviada para: $email');
}
void main() {
// código comentado
Map<String, String> pessoasEmails = {
'joao': 'joao@gmail.com',
'maria': 'maria@gmail.com',
};
print(pessoasEmails.values);
}
Ao executar o código, veremos que ele retorna os e-mails associados às chaves, como o e-mail de João e o e-mail de Maria.
Agora, em vez de simplesmente mostrar esses valores, podemos usar um laço for
para exibir um e-mail de cada vez, o que torna a visualização mais legível. O código ficaria assim:
void enviarEmail(String email) {
print('mensagem enviada para: $email');
}
void main() {
// código comentado
Map<String, String> pessoasEmails = {
'joao': 'joao@gmail.com',
'maria': 'maria@gmail.com',
};
for (String email in pessoasEmails.values) {
print(email);
}
}
Agora, ao executar o código, veremos o e-mail de João e de Maria. Porém, como o objetivo é enviar uma mensagem para esses e-mails, podemos substituir o print
pela nossa função enviarEmail
. O código ficaria assim:
void enviarEmail(String email) {
print('mensagem enviada para: $email');
}
void main() {
// código comentado
Map<String, String> pessoasEmails = {
'joao': 'joao@gmail.com',
'maria': 'maria@gmail.com',
};
for (String email in pessoasEmails.values) {
enviarEmail(email);
}
}
Ao rodar o código, veremos as mensagens sendo enviadas para João e Maria, conforme esperado.
mensagem enviada para: joao@gmail.com
mensagem enviada para: maria@gmail.com
Agora, para garantir que o Enzo também receba a mensagem, podemos adicionar o e-mail dele ao mapa utilizando o comando pessoasEmails['enzo'] = 'enzo@gmail.com'
:
void enviarEmail(String email) {
print('mensagem enviada para: $email');
}
void main() {
// código comentado
Map<String, String> pessoasEmails = {
'joao': 'joao@gmail.com',
'maria': 'maria@gmail.com',
};
pessoasEmails['enzo'] = 'enzo@gmail.com';
for (String email in pessoasEmails.values) {
enviarEmail(email);
}
}
Após executar o código novamente, teremos a mensagem enviada também para o Enzo.
mensagem enviada para: joao@gmail.com
mensagem enviada para: maria@gmail.com
mensagem enviada para: enzo@gmail.
Além disso, talvez tenhamos curiosidade de saber quais são as chaves do mapa — ou seja, os nomes das pessoas. Para isso, em vez de usar values
, podemos usar o método keys
. Ao invés de iterar por email
, vamos iterar por nome
:
void enviarEmail(String email) {
print('mensagem enviada para: $email');
}
void main() {
// código comentado
Map<String, String> pessoasEmails = {
'joao': 'joao@gmail.com',
'maria': 'maria@gmail.com',
};
pessoasEmails['enzo'] = 'enzo@gmail.com';
for (String nome in pessoasEmails.keys) {
print(nome);
}
}
Agora, ao executar o código, veremos os nomes das pessoas presentes no mapa: João, Maria e Enzo.
Com isso, finalizamos o nosso aprendizado sobre mapas e collections. Neste curso, exploramos o funcionamento das listas e seus métodos, as vantagens dos sets e os casos de uso dos maps. Além disso, aprendemos os métodos de cada uma dessas estruturas.
Agora é sua vez! A próxima sessão contém atividades que você pode resolver e compartilhar no fórum. Sinta-se à vontade para compartilhar sua solução ou tirar dúvidas, e eu estarei disponível para responder a cada um de vocês.
Ao final do curso, você verá uma tela de avaliação, e ficarei feliz em receber o seu feedback sobre o que acertamos e o que podemos melhorar.
Muito obrigado e até a próxima!
O curso Praticando Collections no Dart: listas, sets e mapas possui 30 minutos de vídeos, em um total de 14 atividades. Gostou? Conheça nossos outros cursos de Flutter em Mobile, ou leia nossos artigos de Mobile.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.