Primeiras aulas do curso Java: Dominando as Collections

Java: Dominando as Collections

Trabalhando com ArrayList - Trabalhando com ArrayList

Conhecer a API de Collections é algo mais que essencial para o desenvolvedor Java. Elas estão em todos os lugares, você utilizando ou não.

Dentre elas, a ArrayList é a que aparece com maior frequência. Antes de chegarmos em toda a hierarquia das tais "Collections", vamos praticar bastante as operações essenciais das listas, mais especificamente essa implementação. O que são exatamente as Collections? Vai ficar mais claro no decorrer do curso. Pense nelas como classes que ajudam você a manipular um punhado de objetos.

Para esse curso você estará o tempo todo importando classes e interfaces do pacote java.util, fique atento! Caso contrário você pode acabar importando classes de outros pacotes que possuem o mesmo nome.

Crie um novo projeto chamado gerenciador-de-cursos e vamos programar! Mesmo que você já conheça o conteúdo dessas duas primeiras aulas, que envolvem a utilização dos métodos básicos e ordenação, vale a pena recapitular, para então entrarmos em boas práticas, outras coleções e uso no dia a dia de forma real.

Adicionando elementos em uma lista

Para criar um objeto do tipo ArrayList, certamente fazemos como sempre: utilizando o operador new. Mas repare que acabamos passando um pouco mais de informações. Ao declarar a referência a uma ArrayList, passamos qual o tipo de objeto com o qual ela trabalhará. Se queremos uma lista de nomes de aulas, vamos declarar ArrayList<String>. Crie a classe TestandoListas, adicionando os nomes de algumas aulas que teremos nesse curso:

import java.util.List;
import java.util.ArrayList;

public class TestandoListas {

    public static void main(String[] args) {

        String aula1 = "Modelando a classe Aula";
        String aula2 = "Conhecendo mais de listas";
        String aula3 = "Trabalhando com Cursos e Sets";

        ArrayList<String> aulas = new ArrayList<>();
        aulas.add(aula1);
        aulas.add(aula2);
        aulas.add(aula3);        

        System.out.println(aulas);
    }
}

Qual é o resultado desse código? Ele mostra as aulas adicionadas em sequência! Por que isso acontece? Pois a classe ArrayList, ou uma de suas mães, reescreveu o método toString, para que internamente fizesse um for, concatenando os seus elementos internos separados por vírgula.

Removendo elementos

Bastante simples! O que mais podemos fazer com uma lista? As operações mais básicas que podemos imaginar, como por exemplo remover um determinado elemento. Usamos o método remove e depois mostramos o resultado para ver que a primeira foi removida:

aulas.remove(0);
System.out.println(aulas);

Por que 0? Pois as listas, assim como a maioria dos casos no Java, são indexadas a partir do 0, e não do 1.

Percorrendo uma lista

Bem, talvez não seja a melhor das ideias fazer um System.out.println na nossa lista, pois talvez queiramos mostrar esses itens de alguma outra forma, como por exemplo um por linha. Como fazer isso? Utilizando o for de uma maneira especial, chamada de enhanced for, ou popularmente foreach. Lembrando que foreach não existe no Java como comando, e sim como um caso especial do for mesmo. Olhe o código:

for (String aula : aulas) {
    System.out.println("Aula: " + aula);
}

Acessando elementos

E se eu quisesse saber apenas a primeira aula? O método aqui é o get. Ele retorna o primeiro elemento se passarmos o 0 como argumento:

String primeiraAula = aulas.get(0);
System.out.println("A primeira aula é " + primeiraAula);

Você pode usar esse mesmo método para percorrer a lista toda, em vez do tal do enhanced for. Para isso, precisamos saber quantos elementos temos nessa lista. Nesse caso, utilizamos o método size para limitar o nosso for:

for (int i = 0; i < aulas.size(); i++) {
    System.out.println("aula : " + aulas.get(i));
}

Fizemos até i < aulas.size() pois size retorna o total de elementos. Se acessássemos até i <= aulas.size() teríamos um problema! Uma exception do tipo IndexOutOfBoundsException seria lançada! Quer ver? Vamos imprimir o size e faça o teste com o código que temos até aqui:

import java.util.List;
import java.util.ArrayList;

public class TestandoListas {

    public static void main(String[] args) {

        String aula1 = "Modelando a classe Aula";
        String aula2 = "Conhecendo mais de listas";
        String aula3 = "Trabalhando com Cursos e Sets";

        ArrayList<String> aulas = new ArrayList<>();
        aulas.add(aula1);
        aulas.add(aula2);
        aulas.add(aula3);        

        System.out.println(aulas);
        System.out.println(aulas.size());

        // cuidado! <= faz sentido aqui?
        for (int i = 0; i <= aulas.size(); i++) {
            System.out.println("Aula: " + aulas.get(i));
        }
    }
}

Mais uma forma de percorrer elementos, agora com Java 8

Percorrer com o enhanced for é uma forma bastante indicada. Já o for que fizemos utilizando o get possui alguns problemas que veremos em uma próxima aula e vai ficar bastante claro.

Uma outra forma de percorrer nossa lista é utilizando as sintaxes e métodos novos incluídos no Java 8. Temos um método (não um comando!) agora que se chama forEach. Ele recebe um objeto do tipo Consumer, mas o interessante é que você não precisa criá-lo, você pode utilizar uma sintaxe bem mais enxuta, mas talvez assustadora a primeira vista, chamada lambda. Repare:

aulas.forEach(aula -> {
    System.out.println("Percorrendo:");
    System.out.println("Aula " + aula);
});

Estranho não? Lambda não é o foco desse curso. Existe um curso no Alura que vai tratar apenas desse assunto e é bastante aconselhado. Aqui estamos falando que, para cada String aula, determinado bloco de código deve ser executado. Essa variável aula poderia ter o nome que você desejasse.

Ordenando a lista

Esse é bastante fácil quando temos uma List<String>. A classe java.util.Collections (repare o s no final, que é diferente da interface Collection, que será vista mais para a frente) é um conjunto de métodos estáticos auxiliares as coleções. Dentro dela há o método sort:

Collections.sort(aulas);

Simples, não? Mas há bastante mágica ocorrendo aqui por trás. Como é que essa classe sabe ordenar listas de Strings? E se fosse uma lista de, digamos, Aula, também funcionaria? Segure um pouco essas questões e por enquanto vamos fechar esta aula testando esse simples código final:

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

class TestandoListas {

    public static void main(String[] args) {

        String aula1 = "Modelando a classe Aula";
        String aula2 = "Conhecendo mais de listas";
        String aula3 = "Trabalhando com Cursos e Sets";

        ArrayList<String> aulas = new ArrayList<>();
        aulas.add(aula1);
        aulas.add(aula2);
        aulas.add(aula3);        

        System.out.println(aulas);

        Collections.sort(aulas);
        System.out.println("Depois de ordenado:");
        System.out.println(aulas);        
    }
}

O que aprendemos neste capítulo:

Listas de objetos - Listas de objetos

Começando daqui? Você pode fazer o download do projeto completo do capítulo anterior e continuar seus estudos a partir deste capítulo.

Trabalhar com uma lista de Strings foi fácil. E se for de uma classe que nós mesmos criamos? Faz diferença?

Vamos criar uma classe Aula que possui um titulo e o tempo em minutos. Um construtor populará esses atributos. Nem vamos colocar setters, já que não temos essa necessidade por enquanto:

public class Aula {

    private String titulo;
    private int tempo;

    public Aula(String titulo, int tempo) {
        this.titulo = titulo;
        this.tempo = tempo;
    }

    public String getTitulo() {
        return titulo;
    }

    public int getTempo() {
        return tempo;
    }
}

Para brincarmos com objetos do tipo Aula, criaremos uma TestaListaDeAula e adicionaremos aulas dentro de uma List<Aula>:

public class TestaListaDeAula {

    public static void main(String[] args) {

        Aula a1 = new Aula("Revistando as ArrayLists", 21);
        Aula a2 = new Aula("Listas de objetos", 20);
        Aula a3 = new Aula("Relacionamento de listas e objetos", 15);

        ArrayList<Aula> aulas = new ArrayList<>();
        aulas.add(a1);
        aulas.add(a2);
        aulas.add(a3);

        System.out.println(aulas);
    }
}

Qual será o resultado? O nome das três aulas? Na verdade, não. O método toString da classe ArrayList percorre todos os elementos da lista, concatenando seus valores também de toString. Como a classe Aula não possui um toString reescrito (_override_), ele utilizará o toString definido em Object, que retorna o nome da classe, concatenado com um @ e seguido de um identificador único do objeto. Algo como:

[Aula@c3bfe4, Aula@d24512, Aula@c13eaa1]

Se a sua classe Aula estiver dentro de um pacote , e deveria estar, a saída será br.com.alura.Aula@c3bfe4, pois o _full qualified name_, ou _nome completo da classe_, é sempre o nome do pacote concatenado com . e o nome curto da classe.

Reescrevendo nosso toString para trabalhar bem com a lista

Vamos então reescrever nosso método toString da classe Aula, para que ele retorne algo significativo:

public class Aula {

    // ... restante do código aqui

    @Override
    public String toString() {
        return "[Aula: " + this.titulo + ", " + this.tempo + " minutos]";
    }
}

Confira nosso código completo, que você pode fazer pequenas modificações e testar, inclusive removendo o toString por completo:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class TestaListaDeAula {

    public static void main(String[] args) {

        Aula a1 = new Aula("Revistando as ArrayLists", 21);
        Aula a2 = new Aula("Listas de objetos", 20);
        Aula a3 = new Aula("Relacionamento de listas e objetos", 15);

        ArrayList<Aula> aulas = new ArrayList<>();
        aulas.add(a1);
        aulas.add(a2);
        aulas.add(a3);

        System.out.println(aulas);
    }
}

public class Aula {

    private String titulo;
    private int tempo;

    public Aula(String titulo, int tempo) {
        this.titulo = titulo;
        this.tempo = tempo;
    }

    public String getTitulo() {
        return titulo;
    }

    public int getTempo() {
        return tempo;
    }

    @Override
    public String toString() {
        return "[Aula: " + this.titulo + ", " + this.tempo + " minutos]";
    }
}

E se tentássemos adicionar uma String, em vez de uma Aula, dentro dessa lista, o que aconteceria? Faça o teste!

Ordenando uma lista de objetos nossos

O que acontece se tentamos utilizar o Collections.sort em uma lista de Aula?

ArrayList<Aula> aulas = new ArrayList<>();
aulas.add(a1);
aulas.add(a2);
aulas.add(a3);
Collections.sort(aulas);

A invocação Collections.sort(aulas) não compila! Por quê? Pois Collections.sort não sabe ordenar uma lista de Aula. De qual forma ele faria isso? Pelo nome da aula ou pela duração? Não daria para saber.

Mas como ele saberia então ordenar uma List<String>? Será que há um código específico dentro de sort que verifica se a lista é de Strings? Certamente não.

O que acontece é: quem implementou a classe String definiu um critério de comparação entre duas Strings, no qual qualquer pessoa pode comparar dois desses objetos. Isso é feito através do método compareTo. Faça o seguinte teste:

public class TestaComparacaoStrings {

    public static void main(String[] args) {

        String s1 = "paulo";
        String s2 = "silveira";
        int resultado = s1.compareTo(s2);

        System.out.println(resultado);
    }
}

O resultado da comparação é um int, pois um boolean não bastaria. Esse método devolve um número negativo se s1 é menor que s2, um número positivo se s2 é menor que s1 e 0 se forem iguais. Mas o que é maior, menor e igual? No caso da String, quem implementou a classe decidiu que o critério de comparação seria a ordem lexicográfica (alfabética, por assim dizer). Pode ver isso direto na documentação:

https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#compareTo-java.lang.String-

E como nós devemos fazer na classe Aula? Um método parecido? Mais que isso: um método com a mesma assinatura! Pois a String implementa uma interface chamada Comparable, do pacote java.lang, que define exatamente esse método! Você pode ver também que o método Collections.sort recebe uma List de qualquer tipo de objeto que implementa Comparable.

Vamos então implementar essa interface na classe Aula

public class Aula implements Comparable<Aula> {

    // ... restante do código aqui

    @Override
    public int compareTo(Aula outraAula) {
        // o que colocar aqui?
    }
}

É aí que devemos decidir o nosso critério de comparação de duas aulas. Quando uma aula virá antes da outra? Bem, eu vou optar por ordenar na ordem alfabética. Para isso, vou aproveitar do próprio método compareTo da String, delegando:

public class Aula implements Comparable<Aula> {

    private String titulo;
    private int tempo;

    public Aula(String titulo, int tempo) {
        this.titulo = titulo;
        this.tempo = tempo;
    }

    public String getTitulo() {
        return titulo;
    }

    public int getTempo() {
        return tempo;
    }

    @Override
    public String toString() {
        return "[Aula: " + this.titulo + ", " + this.tempo + " minutos]";
    }

    @Override
    public int compareTo(Aula outraAula) {
        return this.titulo.compareTo(outraAula.titulo);
    }
}

Agora podemos testar essa classe no Collections.sort:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class TestaListaDeAula {

    public static void main(String[] args) {

        Aula a1 = new Aula("Revistando as ArrayLists", 21);
        Aula a2 = new Aula("Listas de objetos", 20);
        Aula a3 = new Aula("Relacionamento de listas e objetos", 15);

        ArrayList<Aula> aulas = new ArrayList<>();
        aulas.add(a1);
        aulas.add(a2);
        aulas.add(a3);

        // antes de ordenar:
        System.out.println(aulas);

        Collections.sort(aulas);

        // depois de ordenar:
        System.out.println(aulas);
    }
}

public class Aula implements Comparable<Aula> {

    private String titulo;
    private int tempo;

    public Aula(String titulo, int tempo) {
        this.titulo = titulo;
        this.tempo = tempo;
    }

    public String getTitulo() {
        return titulo;
    }

    public int getTempo() {
        return tempo;
    }

    @Override
    public String toString() {
        return "[Aula: " + this.titulo + ", " + this.tempo + " minutos]";
    }

    @Override
    public int compareTo(Aula outraAula) {
        return this.titulo.compareTo(outraAula.titulo);
    }
}

Ordenando com outro critério de comparação

E se quisermos ordenar essa lista de acordo com o tempo de uma aula? Poderíamos alterar o método compareTo, mas assim todas as ordenações de aulas seriam afetadas.

Uma opção é utilizar o segundo argumento que o Collections.sort recebe. É um comparador, representado pela interface Comparator do pacote java.util (cuidado! o nome é semelhante com Comparable, mas tem um papel bem diferente).

Você pode implementar essa interface e depois invocar Collections.sort(aulas, novoComparadorDeAulas), onde novoComparadorDeAulas é uma instância de um Comparator<Aula>.

Parece complicado? Há uma forma mais enxuta de se fazer isso, utilizando os recursos do Java 8. Não é o nosso foco aqui. Existe um curso exclusivo desse assunto na Alura, mas é sempre bom ir se acostumando. Veja como ficaria:

Collections.sort(aulas, Comparator.comparing(Aula::getTempo));

A frase aqui é semelhante a "ordene estas aulas utilizando como comparação o retorno do método getTempo de cada Aula".

Podemos deixá-la mais bonita. Toda lista, a partir do Java 8, possui um método sort que recebe Comparator. Poderíamos então fazer:

aulas.sort(Comparator.comparing(Aula::getTempo));

O que aprendemos neste capítulo:

Relacionamentos com coleções - Relacionamentos com coleções

Vamos aprimorar nosso modelo de classes para torná-lo mais real. O objetivo é ter uma riqueza de classes e você poder enxergar o dia a dia do uso das coleções.

Para isso, vamos criar uma classe que representa um Curso. Esse Curso vai ter um punhado de Aulas, que representaremos através de uma lista de Aula. Todo curso possuirá também um nome, um instrutor, o construtor que acharmos necessário e também os getters:

public class Curso {

    private String nome;
    private String instrutor;
    private List<Aula> aulas = new LinkedList<Aula>();

    public Curso(String nome, String instrutor) {
        this.nome = nome;
        this.instrutor = instrutor;
    }

    public String getNome() {
        return nome;
    }

    public String getInstrutor() {
        return instrutor;
    }

    public List<Aula> getAulas() {
        return aulas;
    }
}

Opa! Uma LinkedList? Qual é a diferença dela para uma ArrayList? Você vai ver que vamos utilizá-la da mesma forma que uma ArrayList e mais para a frente saberemos as vantagens e desvantagens de cada uma.

Repare que, em vez de declararmos a referência a uma ArrayList<Aula> (ou LinkedList<Aula>), deixamos mais genérico, utilizando a interface List. Por quê? Pelo motivo que já vimos ao estudar orientação a objetos aqui no Alura: não temos motivo para ser super específico na instância que iremos usar. Se forçarmos ArrayList na referência, certamente teremos problema o dia que precisarmos trocar essa lista. Se declararmos apenas como List, poderemos mudar de implementação, como para uma LinkedList, sem problema algum de compilação, por não termos nos comprometido com uma implementação em específico. Fique tranquilo se você ainda não está convencido dessas vantagens. Com tempo de programação e de prática em orientação a objetos isso ficará mais claro.

Vamos testar essa nossa classe Curso, adicionando uma aula e mostrando o resultado:

public class TestaCurso {

    public static void main(String[] args) {

        Curso javaColecoes = new Curso("Dominando as coleções do Java",
                "Paulo Silveira");

        List<Aula> aulas = javaColecoes.getAulas();        
        System.out.println(aulas);
    }
}

O que vai sair aqui? O resultado é [], representando uma coleção vazia. Faz sentido, pois inicializamos nossa lista de aulas com um new LinkedList que estará vazio.

Vamos fazer uma brincadeira com as variáveis para ver se você já está acostumado com a forma que o Java trabalha. E se eu adicionar uma aula no javaColecoes e imprimir novamente o resultado? Será que a variável aulas continuará vazia, já que adicionamos a nova Aula dentro da lista do curso?

Para isso, vamos usar a invocação de javaColecoes.getAulas().add(...). Claro, você pode quebrar essa instrução em duas linhas, mas é bom você se acostumar com uma invocação que logo em seguida faz outra invocação. Nesse caso, estamos invocando o getAulas e logo em seguida invocando o add no que foi retornado pelo getAulas:

public class TestaCurso {

    public static void main(String[] args) {

        Curso javaColecoes = new Curso("Dominando as coleções do Java",
                "Paulo Silveira");

        List<Aula> aulas = javaColecoes.getAulas();        
        System.out.println(aulas);

        javaColecoes.getAulas().add(new Aula("Trabalhando com ArrayList", 21));
        System.out.println(aulas);        
    }
}

O resultado é o esperado por muitos:

[]
[Aula: Trabalhando com ArrayList, 21 minutos]

Isso é apenas para reforçar que trabalhamos aqui com referências. A variável aulas se referencia para uma lista de objetos, que é a mesma que nosso atributo interno do curso em questão se referencia. Isto é, tanto javaColecoes.getAulas() quanto a nossa variável temporária aulas levam ao mesmo local, à mesma coleção.

Tem gente que vai falar que "se mexeu numa variável, mexeu na outra". Não é bem isso. Na verdade, são duas variáveis distintas mas que se referenciam ao mesmo objeto.

Apenas a classe Curso deve ter acesso às aulas

É comum aparecer trechos de código como javaColecoes.getAulas().add(...). É até fácil de ler: pegamos o curso javaColecoes, para depois pegar suas aulas e aí então adicionar uma nova aula.

Mas acabamos violando alguns princípios bons de orientação a objetos. Nesse caso, seria interessante que fosse necessário pedir a classe Curso para que fosse adicionada uma Aula, possibilitando fazer algo como javaColecoes.adiciona(...). E isso é fácil: basta adicionarmos esse método em Curso:

public class Curso {

    private String nome;
    private String instrutor;
    private List<Aula> aulas = new LinkedList<Aula>();

    public Curso(String nome, String instrutor) {
        this.nome = nome;
        this.instrutor = instrutor;
    }

    public String getNome() {
        return nome;
    }

    public String getInstrutor() {
        return instrutor;
    }

    public List<Aula> getAulas() {
        return aulas;
    }

    public void adiciona(Aula aula) {
        this.aulas.add(aula);
    }
}

E com isso podemos fazer:

public class TestaCurso {

    public static void main(String[] args) {

        Curso javaColecoes = new Curso("Dominando as coleções do Java",
                    "Paulo Silveira");

        javaColecoes.adiciona(new Aula("Trabalhando com ArrayList", 21));
        javaColecoes.adiciona(new Aula("Criando uma Aula", 20));
        javaColecoes.adiciona(new Aula("Modelando com coleções", 24));

        System.out.println(javaColecoes.getAulas());
    }
}

Mas quando alguém for usar a classe Curso, ela vai acabar fazendo javaColecoes.adiciona(...) ou javaColecoes.getAulas().add(...)? Se deixarmos assim, ele poderá fazer de ambas as formas.

Queremos que ele só faça da primeira forma, usando nosso novo método adiciona. Como forçar isso? Não há como forçar, mas há como programar defensivamente, fazendo com que o método getAulas devolva uma cópia da coleção de aulas. Melhor ainda: podemos devolver essa cópia de tal forma que ela não possa ser alterada, ou seja, que ela seja não modificável, usando o método Collections.unmodifiableList:

public class Curso {
    /// restante do código...

    public List<Aula> getAulas() {
        return Collections.unmodifiableList(aulas);
    }
}

Veja o código completo abaixo e faça o teste:

import java.util.LinkedList;
import java.util.List;
import java.util.Collections;

public class TestaCurso {
    public static void main(String[] args) {
        Curso javaColecoes = new Curso("Dominando as colecoes do Java",
                    "Paulo Silveira");

        javaColecoes.adiciona(new Aula("Trabalhando com ArrayList", 21));
        javaColecoes.adiciona(new Aula("Criando uma Aula", 20));
        javaColecoes.adiciona(new Aula("Modelando com colecoes", 24));

        // tentando adicionar da maneira "antiga". Podemos fazer isso? Teste:
        javaColecoes.getAulas().add(new Aula("Trabalhando com ArrayList", 21));

        System.out.println(javaColecoes.getAulas());
    }
}
public class Curso {

    private String nome;
    private String instrutor;
    private List<Aula> aulas = new LinkedList<Aula>();

    public Curso(String nome, String instrutor) {
        this.nome = nome;
        this.instrutor = instrutor;
    }

    public String getNome() {
        return nome;
    }

    public String getInstrutor() {
        return instrutor;
    }

    public List<Aula> getAulas() {
        return Collections.unmodifiableList(aulas);
    }

    public void adiciona(Aula aula) {
        this.aulas.add(aula);
    }
}
public class Aula implements Comparable<Aula> {

    private String titulo;
    private int tempo;

    public Aula(String titulo, int tempo) {
        this.titulo = titulo;
        this.tempo = tempo;
    }

    public String getTitulo() {
        return titulo;
    }

    public int getTempo() {
        return tempo;
    }

    @Override
    public String toString() {
        return "[Aula: " + this.titulo + ", " + this.tempo + " minutos]";
    }

    @Override
    public int compareTo(Aula outraAula) {
        return this.titulo.compareTo(outraAula.getTitulo());
    }
}

Repare que uma exception será lançada ao tentarmos executar javaColecoes.getAulas().add. Qualquer tentativa de modificação vai lançar essa exception, indicando algo como "opa! você não pode alterar o estado dessa coleção aqui, encontre outra forma de fazer o que você quer".

LinkedList ou ArrayList?

E o mistério da LinkedList? E se tivéssemos usado ArrayList na declaração do atributo aulas da classe Curso? O resultado seria exatamente o mesmo!

Então qual é a diferença? Basicamente performance. O ArrayList, como diz o nome, internamente usa um array para guardar os elementos. Ele consegue fazer operações de maneira muito eficiente, como invocar o método get(indice). Se você precisa pegar o décimo quinto elemento, ele te devolverá isso bem rápido. Quando um ArrayList é lento? Quando você for, por exemplo, inserir um novo elemento na primeira posição. Pois a implementação vai precisar mover todos os elementos que estão no começo da lista para a próxima posição. Se há muitos elementos, isso vai demorar... Em computação, chamamos isso de consumo de tempo linear.

Já o LinkedList possui uma grande vantagem aqui. Ele utiliza a estrutura de dados chamada lista ligada, e é bastante rápido para adicionar e remover elementos na cabeça da lista, isto é, na primeira posição. Mas é lento se você precisar acessar um determinado elemento, pois a implementação precisará percorrer todos os elementos até chegar ao décimo quinto, por exemplo.

Confuso? Não tem problema. Sabe o que é interessante? Você não precisa tomar essa decisão desde já e oficializar para sempre. Como utilizamos a referência a List, comprometendo-nos pouco, podemos sempre mudar a implementação, isso é, em quem damos new, caso percebamos que é melhor uma ou outra lista nesse caso em particular.

Se você gosta desse assunto e gostaria de conhecer profundamente os algoritmos e estruturas de dados por trás das coleções do Java, há o curso de estrutura de dados com esse enfoque, que você pode acessar Aqui

O que aprendemos neste capítulo:

Sobre o curso Java: Dominando as Collections

O curso Java: Dominando as Collections possui 170 minutos de vídeos, em um total de 62 atividades. Gostou? Conheça nossos outros cursos de Java 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 Java acessando integralmente esse e outros cursos, comece hoje!

  • 1017 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

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • 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

  • 1017 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

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • 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

  • 1017 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

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • 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

  • 1017 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

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • 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
Procurando planos para empresas?
Acesso por 1 ano
Estude 24h/dia onde e quando quiser
Novos cursos toda semana