Primeiras aulas do curso Kotlin Collections: Set e Map

Kotlin Collections: Set e Map

Conhecendo a base de Collection - Introdução

Eu sou o Alex Felipe, instrutor aqui da Alura, e vou apresentar para você o curso de collections no Kotlin. Para esse curso, vou assumir que você já tenha conhecimento no Kotlin em relação a arrays e listas, que são falados no curso que vou deixar como pré-requisito aqui para este.

Caso você não tenha tanto conhecimento assim e mesmo qualquer continuar, fique à vontade. Mas entenda que algumas coisas não serão explicadas por conta disso, porque já vou assumir que você tenha esse conhecimento. Até mesmo no uso de alguns comportamentos que a gente vai ver aqui.

Dado que passei essa parte do pré-requisito, o que a gente vai ver de verdade? Basicamente, a gente vai explorar toda essa documentação que temos de collections. Vamos entender o que significa esse tal de collection aqui no Kotlin. A gente vai perceber que ela é a base para que a gente tenha essas estruturas, que possuem mais de um objeto, mais de um elemento, números, assim por diante, assim como tínhamos nas listas.

Vamos notar que a collection é a base para a lista. A lista vem da collection. Veja que existe uma hierarquia que a gente vai explorar durante esse curso, que é entender o que é essa referência de collection, iterable, list, set, map, e até mesmo suas outras versões, que envolvem esse mutable iterable, mutable collection, mutable list, mutable set, e esse mutable map.

Vamos vasculhar cada uma dessas referências e entender quais são seus objetivos, diferenças, quando utilizar uma, quando utilizar outra. Perceba que nossa ideia é realmente pegar situações do nosso dia a dia que podemos considerar cada uma dessas referências.

A lista a gente já percebeu que serve para a gente ter mais de um elemento em uma estrutura, que a gente pode passar por cada um desses elementos, a gente pode pegar por meio da sua ordem, e assim por diante. Só que aqui no set, no map, a gente vai perceber que existem outras situações, outras características que acabam sendo mais interessantes.

Vamos entender também que a gente pode reaproveitar código, na ideia de polimorfismo, parte de collection, iterable, e que também vão existir coisas muito específicas que vêm do set, do map, que podem ser úteis no nosso dia a dia. Isso de maneira bem genérica, independente da regra de negócio.

A ideia é realmente a gente aprender comportamentos muito comuns. A gente vai ver que vão existir operações específicas para o map, para o set, para lista, vamos entender que existem comportamentos de transformações, de agrupamento, e assim por diante.

A ideia do curso é que tenhamos esse primeiro contato com essa documentação bem vasta da collections, para que dessa forma a gente conseguia tanto aprender, introduzir o que são collections, como também ter essa oportunidade agora de vasculhar a documentação e ver diversos comportamentos que a gente pode usar nos nossos códigos.

Eu espero que você esteja animado com o conteúdo e conto com sua presença para a nossa primeira aula. Vamos começar?

Conhecendo a base de Collection - Introdução a Collections

Como primeiro passo vamos começar nessa página documentação que é a Kotlin Collections Overview. Uma visão geral do que a gente pode ter de collections dentro do Kotlin. Se a gente pega todo esse texto apresentado para nós na documentação, vai fazer um resumo do que são as collections e o que a biblioteca padrão do Kotlin tem para oferecer para esse recurso.

Pode vir aquela questão. O que é uma collection? Basicamente uma collection vai ser uma referência que a gente vai ter no Kotlin para gerenciar vários tipos de variáveis. Podemos gerenciar uma collection que vai representar strings, que vai representar inteiros, que vai representar objetos nossos, assim como vimos na list.

Então, a list é sim representada por uma collection. É ela que define o que é uma lista. Se a gente pega essa parte da documentação, a gente percebe que toda essa introdução de collection é feita para a gente.

Dado que a gente sabe o que é uma lista, que vai ser uma estrutura de um conjunto de variáveis que tem a mesma relação, uma lista de strings, uma lista de inteiros, uma lista de objetos nossos, a collection tem essa mesma ideia.

Nosso objetivo agora é entender o que tem de estrutura em relação da collection, em relação da lista, para a gente saber como funciona por debaixo dos panos.

Onde a gente vai explorar essa estrutura? Vai ser nessa parte da documentação também. Toda essa outra parte que a gente viu aqui vou deixar como referência para você, para você ler e estudar, para ter mais informações se for do seu interesse. Se você já veio de outra linguagem de programação, que você já conhece as collections dessas outras linguagens, até mesmo a documentação cita aqui, se você tem essa familiaridade, como é o caso do Java e Python, você pode até pular essa introdução porque vai ser a mesma coisa.

Só que agora a gente vai ver algumas especificações que tem no Kotlin para entender toda essa estrutura. O primeiro ponto que a gente tem que notar, assim como a gente viu na lista, é que toda collection vai ter essa ideia de read only e mutable, que seria uma coleção que só pode ser lida não vai ter nenhum tipo de comportamento, de alteração, e uma collection que vai também, além de ser lida, ter esse comportamento de modificação, assim como a gente viu na lista.

Na lista a gente tem o list e o mutable list, para poder fazer as modificações, então toda collection que a gente vê do Kotlin, seja list ou outra que a gente vai ver aqui, vai ter esse comportamento que a gente está vendo aqui, tanto o read only, apenas para leitura, quanto o mutable, que também tem comportamentos de mutação. Ela pode ser modificada.

O que a gente vai explorar nesse primeiro momento é esse diagrama aqui, que é onde quero chegar com você, porque ej a partir dele que a gente consegue entender de verdade a estrutura de uma collection.

A gente pode identificar referências que a gente conhece da list. A gente percebe que a list está um pouco mais abaixo. Existem outras referências que são mais genéricas, superiores, que apresentam a base de como tudo funciona. A gente vê que da lista, quem ela herda é justamente do collection do iterable, que são essas duas referências que a gente vai entender agora o que representam para nós.

Para ser mais prático e não ficar tanto na teoria, vou entrar no IntelliJ e vamos escrever alguns códigos para ver como funciona essa tal de collection e iterable. Para isso, vou começar com uma lista, que é o que a gente conhece até então.

A gente vai ter aqui um list of, e esse list of vou fazer de nomes. Vou colocar meu nome, que seria Alex, a Fran, o Gui, a Maria e a Ana. Apenas para ter como exemplo, fique à vontade para colocar os nomes que você preferir.

Vou atribuir isso aqui para uma variável chamada nomes. Quando a gente faz isso a gente já sabe que estamos lidando com o list de strings a partir do generics que a gente já aprendeu. Toda essa estrutura de collection vai ter essa ideia de generics também. A gente pode até mesmo colocar o nome de list string.

Temos uma lista de string. Vou pular algumas linhas nos argumentos com o put arguments on separate lines, e beleza. Temos nossa lista. Se a gente faz uma impressão temos o resultado que esperamos, então vou fazer essa impressão com print. Vou até usar um template do IntelliJ, que é o sout.

Se a gente faz essa execução temos um comportamento já esperado, que a gente já viu nos cursos anteriores, que fala sobre array e list, e aqui temos os nomes que a gente colocou dentro da nossa lista.

Só que agora tem um detalhe. Como a gente viu, a lista vai ter como referência mais genérica a collection. Vamos ver o que acontece quando a gente coloca como collection. Se a gente deixar como collection e executar, porque não teve nenhum problema de compilação, a gente tem exatamente o mesmo resultado.

E se a gente faz também o uso do iterable a gente vai perceber que temos exatamente o mesmo resultado. Em outras palavras, quando estamos falando de collections, dessas referências mais genéricas, a gente está indicando qual a estrutura base de qualquer tipo de coleção que a gente colocar dentro do Kotlin. Qualquer tipo de coleção, seja list ou set como a gente está vendo aqui vão compartilhar os mesmos comportamentos que a gente tem do iterable e do collection, que vão ser comuns para todos.

Por exemplo, aqui no iterable, como estou implementando uma list, se eu colocar aquele set, que é o que a gente viu ali, que tem também uma implementação fácil, que é o set of, a gente vai perceber que o código compila e funciona da mesma maneira.

Veja que nessa breve introdução que a gente teve já podemos concluir que no momento em que queremos reutilizar os mesmos comportamentos de diferentes implementações de coleções, que é o caso do set ou do list, a gente pode utilizar essas referências mais genéricas. Só que aí vai ter alguns detalhes.

Como a gente já aprendeu de polimorfismo, quando a gente utiliza uma referência mais genérica, a gente fica mais restrito a alguns comportamentos. Qual seria essa restrição de comportamentos que a gente tem, por exemplo, no iterable? O iterable é a referência mais simples possível para dar capacidade para a gente fazer a iteração entre elementos.

Quando a gente faz um for loop e pega um nome dos nomes, como a gente já aprendeu aqui, o iterable é capaz de colocar esse comportamento para qualquer tipo de collection. É por meio dele que a gente tem esses comportamentos. Se a gente faz agora essa impressão que vai por cada elemento, a gente vê que ele tem esse comportamento numa boa, seja o set ou o list.

Novamente, quer usar algo mais genérico e que é um comportamento comum entre todas as coleções, ou até mesmo do iterable, você pode considerar essa referência. Para deixar mais claro, essa referência é uma interface cujo objetivo é justamente fazer com que a gente tenha esse comportamento de sequência, que a gente consegue iterar nossos elementos.

Quem faz isso por debaixo dos panos é uma referência chamada iterator. A gente tem um método para cada iterable, que é esse iterator, que devolve essa outra referência a gente viu. Esse iterator trata-se de uma interface, que vai ser o responsável em mostrar ou implementar o comportamento para representar cada elemento da nossa coleção ou estrutura de elementos.

É ele que fica responsável em pegar o primeiro elemento, passar para o próximo, para o próximo, para que então a gente consiga usar o nosso for loop da maneira que a gente usa.

Independente se seja iterable ou collection, sempre teremos esse comportamento de iterator. Então qualquer um que seja algum deles vai ter que ter essa implementação. Até mesmo a list, se a gente pegar a list a gente vai ver que ela vai também implementar o iterator.

Se a gente executar aqui, vamos ver que funciona numa boa. Essa é a breve introdução que a gente pode ter desse recurso do iterable. Tirando o iterator e voltando para o nosso iterable, o que a gente pode tirar mais de comportamentos?

Podemos ver também. Podemos chegar abaixo, depois que pegamos os nomes e podemos pegar nomes e ver os comportamentos que temos aqui. Se a gente pesquisar, por exemplo, o contains, que é um comportamento bastante comum em collections, que verifica se tem um elemento, a gente pode verificar, por exemplo, se tem o Alex. Até mesmo colocar dentro de uma impressão. Estou colocando impressão e o que vou verificar vai ser o seguinte. Colocando a pergunta tem o nome Alex, e aqui coloco nosso comportamento dentro do string template.

A gente vai executar e vamos ver que funciona numa boa. Só que o nosso iterable, como é uma referência mais básica, vamos ficar mais restritos ao comportamento. Às vezes não vamos ter esse interesse em fazer esse polimorfismo em relação a ele porque é mais limitado. Nesse caso a gente sempre vai abaixando nosso nível, que seria justamente colocar o collection, uma extensão, algo a mais que a gente tem do iterable.

Os mesmos comportamentos que a gente viu do iterable funcionam, só que aqui a gente vê que tem mais comportamentos. Então, nomes size seria um comportamento que apenas a collection tem. A partir da collection a gente começa a ter esse comportamento.

Se eu chegar aqui e colocar um sout para poder colocar uma impressão e verificar tamanho da coleção, a partir do nosso size, a gente vai perceber que a gente vai ter esse comportamento só na collection. Vou colocar nomes, size, vamos executar, a gente vai ver que funciona, e no momento que a gente quer pegar, que é o iterable, e querer também reutilizar esse comportamento a gente não vai ter.

É uma das observações que você pode considerar. A ideia no geral é usar o polimorfismo para reutilizar comportamentos, porque de repente você quer fazer uma solução genérica, você vai utilizar uma dessas referências, só que se nessa solução genérica você precisar de algo mais específico você apela para o mais específico. Mais específico que tem mais comportamentos seria o collection, mas se de repente o collection também não tem você pode utilizar a list e a partir dela você vai ter os mesmos comportamentos, só que as coisas a mais que uma lista tem e que de repente uma collection não tem.

Essa é a primeira introdução que a gente pode ter aqui das collections, que é uma estrutura na qual a gente vai ter essa estrutura de coleção de elementos, que seria uma lista, um set, assim por diante, só que temos essas referências mais básicas para que a gente consiga fazer uso do polimorfismo e dar essas soluções mais genéricas, como também já atribuí os comportamentos padrões que qualquer tipo de lista, set ou coleção que a gente implemente ou reutilize deva ter.

Conhecendo a base de Collection - Tipos de coleção

Agora que conhecemos as referências iterable e collection podemos partir para o próximo assunto, que é para falar a respeito dos tipos de coleções. Como já vimos, temos dois tipos, o read only, que são referências que não permitem modificar os valores, e a mutable, que já são referências que além da leitura do read only também permitem fazer a modificação dos valores.

Como a gente pode ver no exemplo aqui, temos essa referência, que é o mutable list of, que adiciona algumas palavras que são os números por extenso e depois permite adicionar mais um número por extenso depois que é criada a lista.

Essa característica que a gente está vendo aqui é uma característica comum em referências mutable, collections do tipo mutable. Quando a gente aprendeu tanto a collection como o iterable e vimos que a lista herda diretamente delas, a gente pode concluir que aqui temos referências read only. A gente não consegue fazer a modificação dos elementos a partir dessas referências.

Para isso, a gente vai ter outras referências que herdam delas. Do iterable, a gente vai ter outra referência chamada de mutable iterable que herda dela. Da collection a mutable collection, e da list como a gente já viu a mutable list.

O que a gente pode tirar de informação daqui? Da mesma maneira como a gente viu aquela ideia de polimorfismo, aqui também pode ser aplicado nas mutáveis. Por exemplo, agora vou utilizar uma referência de mutable list para poder ter essa ideia de mutável. A primeira coisa que a gente tem que ver é que a implementação de list já não é mais compatível, então aqui tem que ser o mutable list of.

Quando a gente tem esse mutable list, olha o que acontece. A gente vai ter aqui a mesma ideia que a gente viu antes também na collection. Então mutable collection. A gente consegue ter a mesma referência. Da mesma forma, a gente tem o mutable iterable. A gente consegue fazer esse mesmo uso.

Só que aqui vão vir as mesmas questões que a gente viu anteriormente. Tem um comportamento específico? O iterable de repente não vai ter. Começa já pelo size. Mas também como a gente já viu, quando a gente trabalha com uma lista no mutable a gente tem aquele comportamento de adição. Se quero adicionar, por exemplo, o Paulo, eu usaria esse método. E também aqui no mutable iterable não temos.

Veja que o mutable iterable sempre vai ser a referência mais restrita. Então se é um comportamento que não tem nele, novamente a gente vai lá e baixa um pouco o nível, para poder fazer nossa solução ser mais genérica usando os recursos que a gente quer dos tipos de coleções possíveis.

Agora que estou adicionando aqui o Paulo já consigo fazer uso de uma coleção mutável. Agora quero fazer uma remoção. Também consigo fazer a partir da referência do mutable collection.

Só para remover o Alex e deixar o Paulo a gente vê que nosso código funciona numa boa. Não tem mais o nome do Alex. A gente vê na impressão que não tem. A coleção tem tamanho 5, e assim por diante.

Agora que tivemos também essa nova introdução para falar dos tipos de coleções vou aproveitar esse momento para implementar um código bastante comum no nosso dia a dia, que envolve essa solução de uma coleção mutável, que a gente vai ver que tem alguns cuidados que a gente tem que tomar que vou explorar agora com vocês. Vamos começar.

Para isso vou novamente voltar com esse código para que ele seja um código apenas de leitura. Como a gente pode ver, mesmo tendo uma implementação mutável a gente pode retornar uma referência imutável. Mesmo que internamente a gente sabe que pode mudar, externamente, vamos chamar assim, da maneira que a gente usa aqui a gente não consegue mais, porque a gente está indicando que aqui a gente trabalha com a referência imutável.

É o mesmo caso dos funcionários. A gente sabia que tinha um analista, um diretor, mas a gente não tinha uma bonificação ou algo específico do funcionário, mas sim apenas as coisas específicas do funcionário só, da referência mais genérica. Aqui aplica a mesma coisa, porque esse aqui é bem compatível, tem essa questão da herança. Eles são compatíveis.

Agora que a gente fez essa modificação, o primeiro passo para a gente começar nossa solução nova é extrair isso para uma função. Testa coleção, que foi o que a gente fez aqui. Vou deixar como público para depois mandar para um arquivo com mais facilidade.

Vou fazer essa solução que falei que vou usar um pouco desse mutable para mostrar umas coisas que podem ser comuns no dia a dia, que vai ser uma solução que vai simular um banco de dados de nome, que vai ter a responsabilidade de guardar as informações e permitir que a gente consiga adicionar, remover, enfim, essas operações que são comuns em leitura e escrita.

Vou criar uma classe chamada banco de nomes para conseguir representar isso aqui no nosso código. Para ter esse comportamento de modificação, qual a primeira coisa que precisamos fazer? Precisamos ter uma estrutura que permita essa modificação. A gente precisa ter o mutable list of.

Para ele fazer o auto complete primeiro vou criar uma variável que vai representar nossos dados. Vou chamar até mesmo de nomes. Vai ter o mutable, ele já mostra para nós, fica mais fácil, e essa é a primeira estrutura que a gente precisa ter.

Dado que é um banco de nomes e que quem vai adicionar é quem utilizar nosso código, não faz muito sentido colocar um Alex aqui. Não pode ter nomes logo de cara. A gente só precisa indicar qual o tipo de dado que a gente vai trabalhar aqui. Nesse caso, como a gente sabe que a gente trabalha com generics dentro da lista, ou melhor, das coleções, a gente pode colocar que vai ser uma lista mutável de strings.

Com essa breve implementação aqui a gente já consegue fazer alguns testes. Consigo criar um banco de nomes, e aqui vou chamar de banco, não tem nenhum problema, a gente pode fazer isso.

A primeira coisa que vou fazer é ler os nomes que a gente colocou, que no caso não tem nenhum nome, mas a gente vai ver que já funciona, que é uma lista vazia. Isso é bastante comum também aqui dentro de coleções, a gente trabalhar com listas vazias. Muito comum mesmo.

Agora que a gente tem essa breve introdução, qual seria o próximo passo? A adição de nomes. Dado que a adição de nomes é o próximo passo a gente pode simplesmente pegar o nomes, dado que é mutável, e fazer uma adição. Vou colocar o Alex agora e a gente vai ver que funciona, só que temos alguns dos detalhes que é uma das primeiras coisas que temos que ficar atentos quando trabalhamos com coleções, principalmente as mutáveis.

Nesse tipo de abordagem que a gente está vendo aqui estamos quebrando os princípios da orientação a objetos, que envolve a questão de encapsulamento, porque o responsável por manipular as informações internas não pode deixar que qualquer um de fora faça essa manipulação, porque dessa forma a gente perde até mesmo a confiabilidade no código, uma vez que a gente acha que nosso código vai ser responsável o suficiente para expor os comportamentos possíveis de tal forma que a gente consiga filtrar, evitar algumas coisas que o banco de nomes precisa fazer.

Se de repente a gente precisasse fazer uma validação antes de adicionar esse nome, da maneira como está aqui a gente não consegue mais fazer isso, porque qualquer um de fora consegue fazer o que quiser com nossa coleção.

Veja que aqui a gente precisa ter alguns cuidados. O primeiro deles é justamente restringir qualquer tipo de acesso de coleção que seja mutável. Isso é necessário em qualquer solução que você fizer. Vai trabalhar com alguma coleção mutável? Evite o máximo possível deixar ela exposta para qualquer um de fora. Sempre tente trabalhar com o modo privado.

Dado que agora a gente está trabalhando com o modo privado, como a gente pode fazer para que a gente exponha essas informações? Uma das maneiras que a gente pode fazer é criar mais uma property, que pode se chamar princípio de nomes. Essa property vai ser uma collection de string apenas de leitura. E dado que é uma collection de string apenas de leitura, a gente pode fazer com que sua implementação devolva esse outro nomes que a gente está vendo.

Só que dado que é o mesmo nome a gente tem que fazer algumas modificações. Internamente, pouco importa se isso se chama nomes ou não. Pode se chamar dados, qualquer coisa. Pouco importa para a gente. O importante é para quem realmente vai ver as outras informações dos nomes, que é essa parte da coleção apenas de leitura.

Veja que dessa forma, como fizemos aqui, olha o que aconteceu. Conseguimos fazer com que nossa solução evitasse que qualquer um de fora tivesse acesso aos nossos dados, internamente. Os que podem ser modificados. E agora não pode realmente adicionar o Alex ou qualquer outro nome, ou remover. Ele não pode fazer nada, apenas a leitura.

Esse é um primeiro ponto a se notar quando a gente trabalha com o mutable. É que a gente não pode fazer com que qualquer um consiga manipular nossa coleção. Aí dado que o objetivo é permitir fazer a adição, aí sim a gente pode colocar aqui um método, que seria o salva, que recebe um nome, do tipo string, e ele vai lá e coloca dentro do dados. É o add nome.

Dessa maneira, quando a gente agora trabalhar com nosso banco, a gente ao invés de usar o head internamente, a gente utiliza o salva, que agora sim o salva pode mudar o Alex, porque dessa maneira, por mais que ele seja exatamente a mesma coisa que a gente está fazendo aqui em cima, aqui a gente tem muito mais poder de controle.

A gente não está permitindo que qualquer um consiga adicionar diretamente, ou consiga remover diretamente. A gente nem permite que a remoção seja feita e apenas seja salva as informações. Por isso que é muito importante a gente tomar esses cuidados.

Tem mais um detalhe, agora só para finalizar, que dessa maneira como a gente fez, sempre que a gente criar um objeto vai limpar nossa lista, porque cada objeto vai ter uma lista diferente. Se chegar aqui e colocar nomes, uma instância, e pegar os nomes, banco de nomes, e lista de nomes, a gente vai perceber que os dados serão diferentes, porque a gente está sempre atrelando aqui nossa mutable list para o objeto.

Uma das coisas que a gente pode fazer, que a gente aprendeu em outros cursos é colocar como companion. “Alt + Enter” em dados, move to companion object. Aí se tornando companion object, olha o que vai acontecer. Ele colocou o companion antes, não é necessários, vou até tirar aqui.

Dessa maneira como a gente está colocando agora, olha como fica. Ao executar o código a gente vai perceber que os dados serão mantidos. Se a gente salvou alguma vez em algum lugar eles serão mantidos, mesmo que seja uma property, que sejam comportamentos, membros vinculados ao objeto, porque no companion object a gente consegue ter esse tipo de comportamento.

É uma das coisas que a gente pode estar fazendo para melhorar mais ainda a experiência do nosso código. Então, veja que ao trabalhar com coleções, mais específicas as coleções mutáveis, a gente tem que ter esse cuidado para restringir o máximo possível, expor os comportamentos apenas que a gente quer que a pessoa que vai utilizar nosso código tenha, e que no momento que a gente quer permitir a leitura a gente pode utilizar toda essa estrutura que a gente aprendeu aqui, dos tipos de coleções, que podem ser leitura e mutáveis, e expomos sempre o máximo possível imutáveis, para que a pessoa leia e evite modificar nosso código.

Era isso que eu queria passar para vocês.

Sobre o curso Kotlin Collections: Set e Map

O curso Kotlin Collections: Set e Map possui 147 minutos de vídeos, em um total de 39 atividades. Gostou? Conheça nossos outros cursos de Kotlin em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Kotlin acessando integralmente esse e outros cursos, comece hoje!

  • 1266 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

Premium

  • 1266 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$75
à vista R$900
Matricule-se

Premium Plus

  • 1266 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$100
à vista R$1.200
Matricule-se

Max

  • 1266 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$120
à vista R$1.440
Matricule-se
Conheça os Planos para Empresas

Acesso por 1 ano

Estude 24h/dia onde e quando quiser

Novos cursos todas as semanas