AFF Education Construa seu Futuro

Aula 54 - Revisão: ArrayList versus Vetor []

Comparação entre arrays tradicionais e ArrayList, tipos de referência e autoboxing

Introdução ao ArrayList

O ArrayList é uma estrutura de dados dinâmica do Java que faz parte do pacote java.util. Diferentemente dos arrays tradicionais ([]), o ArrayList pode crescer e diminuir de tamanho conforme necessário.

Diferença principal:

Comparação: Array vs ArrayList

Vetor Tradicional (Array)

Diagrama do for-each iterando sobre array de Strings nomes
Figura 13 — Visualização do for-each percorrendo o array de Strings nomes ({"Ana", "Bruno", "Carlos", "Diana", "Eduardo"}). A cada iteração, nome recebe um dos valores do array — o tamanho fixo do array define exatamente quantas vezes o laço executa.
public class ExemploArray {
    public static void main(String[] args) {
        // Tamanho fixo: 5 elementos
        String[] nomes = new String[5];

        // Adicionando elementos manualmente
        nomes[0] = "Ana";
        nomes[1] = "Bruno";
        nomes[2] = "Carlos";
        nomes[3] = "Diana";
        nomes[4] = "Eduardo";

        // Tamanho fixo - não pode adicionar mais elementos
        System.out.println("Tamanho do array: " + nomes.length);

        // Percorrendo o array
        for (String nome : nomes) {
            System.out.println(nome);
        }
    }
}

Tamanho do array: 5

Ana

Bruno

Carlos

Diana

Eduardo

ArrayList (Tamanho Dinâmico)

import java.util.ArrayList;

public class ExemploArrayList {
    public static void main(String[] args) {
        // Criando ArrayList sem definir tamanho
        ArrayList<String> nomes = new ArrayList<>();

        // Adicionando elementos dinamicamente
        nomes.add("Ana");
        nomes.add("Bruno");
        nomes.add("Carlos");
        nomes.add("Diana");
        nomes.add("Eduardo");

        // Pode adicionar mais elementos a qualquer momento
        nomes.add("Fernanda");
        nomes.add("Gabriel");

        System.out.println("Tamanho do ArrayList: " + nomes.size());

        // Percorrendo o ArrayList
        for (String nome : nomes) {
            System.out.println(nome);
        }
    }
}

Tamanho do ArrayList: 7

Ana

Bruno

Carlos

Diana

Eduardo

Fernanda

Gabriel

Tabela Comparativa: Array vs ArrayList

Característica Array [] ArrayList
Tamanho Fixo Dinâmico
Declaração int[] nums = new int[5]; ArrayList<Integer> nums = new ArrayList<>();
Adicionar elemento nums[0] = 10; nums.add(10);
Acessar elemento nums[0] nums.get(0)
Tamanho nums.length nums.size()
Remover elemento Não suportado nums.remove(0)
Tipos primitivos Suporta diretamente Requer wrapper (Integer, Double, etc.)

ArrayList e Tipos de Referência: o que vai entre <>?

Sim, o ArrayList sempre precisa que você especifique o tipo entre <> — mas com uma ressalva importante: ArrayList só aceita tipos de referência (objetos), não tipos primitivos.

✔ Declarações corretas:

✘ Declaração incorreta — erro de compilação:

Tabela: Primitivo → Wrapper para ArrayList

Tipo Primitivo Classe Wrapper (use no ArrayList) Exemplo de declaração
int Integer ArrayList<Integer> nums = new ArrayList<>();
double Double ArrayList<Double> precos = new ArrayList<>();
char Character ArrayList<Character> letras = new ArrayList<>();
boolean Boolean ArrayList<Boolean> flags = new ArrayList<>();
float Float ArrayList<Float> valores = new ArrayList<>();
long Long ArrayList<Long> ids = new ArrayList<>();

Autoboxing e Unboxing

O Java faz a conversão automática entre o tipo primitivo e seu wrapper. Isso se chama autoboxing (primitivo → objeto) e unboxing (objeto → primitivo). Na prática, você escreve int mas o ArrayList recebe Integer automaticamente.

import java.util.ArrayList;

public class AutoboxingDemo {
    public static void main(String[] args) {
        ArrayList<Integer> numeros = new ArrayList<>();

        // autoboxing: int 42 é convertido para Integer automaticamente
        numeros.add(42);
        numeros.add(100);
        numeros.add(7);

        // unboxing: Integer é convertido de volta para int automaticamente
        int primeiro = numeros.get(0);

        System.out.println("Lista: " + numeros);
        System.out.println("Primeiro elemento: " + primeiro);
        System.out.println("Soma dos dois primeiros: " + (numeros.get(0) + numeros.get(1)));
    }
}

Lista: [42, 100, 7]

Primeiro elemento: 42

Soma dos dois primeiros: 142

💡 Dica: Graças ao autoboxing, você raramente precisa se preocupar com a conversão entre int e Integer — o Java cuida disso nos bastidores. Mas lembre-se: a declaração do ArrayList ainda exige o wrapper (Integer, não int).

A Regra do Diamond Operator <>

O <> vazio (chamado de diamond operator) só é válido no lado direito da atribuição, onde o compilador consegue inferir o tipo pelo lado esquerdo.

✔ Correto: tipo declarado na esquerda, <> inferido na direita

// O compilador lê "ArrayList<String>" na esquerda e infere o tipo na direita
ArrayList<String> lista = new ArrayList<>();

✘ Erro de compilação: <> na esquerda — o compilador não tem como inferir o tipo

// ERRO: compilador não sabe qual tipo usar no lado esquerdo
ArrayList<> lista = new ArrayList<String>();  // não compila!

⚠ Atenção — Raw Type (sem nenhum tipo): Tecnicamente é possível usar ArrayList sem <> (chamado de raw type), mas é má prática pois perde a segurança de tipos em tempo de compilação e pode gerar alertas de unchecked warning.

// Má prática — raw type, evite!
ArrayList lista = new ArrayList();
lista.add("texto");
lista.add(42);   // aceita qualquer coisa — sem segurança de tipos

Resumo da regra:

Criando ArrayList de Diferentes Tipos

ArrayList pode armazenar diferentes tipos de objetos (um ArrayList por tipo):

import java.util.ArrayList;

public class ArrayListTipos {
    public static void main(String[] args) {
        // ArrayList de Strings
        ArrayList<String> frutas = new ArrayList<>();
        frutas.add("Maçã");
        frutas.add("Banana");
        frutas.add("Laranja");

        // ArrayList de Integer (wrapper de int — não pode usar int diretamente)
        ArrayList<Integer> numeros = new ArrayList<>();
        numeros.add(10);   // autoboxing: int → Integer
        numeros.add(20);
        numeros.add(30);

        // ArrayList de Double (wrapper de double)
        ArrayList<Double> precos = new ArrayList<>();
        precos.add(19.99);  // autoboxing: double → Double
        precos.add(29.50);
        precos.add(15.75);

        // ArrayList de Boolean (wrapper de boolean)
        ArrayList<Boolean> status = new ArrayList<>();
        status.add(true);
        status.add(false);
        status.add(true);

        System.out.println("Frutas: " + frutas);
        System.out.println("Números: " + numeros);
        System.out.println("Preços: " + precos);
        System.out.println("Status: " + status);
    }
}

Frutas: [Maçã, Banana, Laranja]

Números: [10, 20, 30]

Preços: [19.99, 29.5, 15.75]

Status: [true, false, true]

Por que 29.5 e não 29.50? O método toString() do Java remove zeros à direita em números decimais. Para formatar com duas casas decimais, use String.format("%.2f", valor).

For Loop com ArrayList

Existem diferentes formas de percorrer um ArrayList:

import java.util.ArrayList;

public class PercorrerArrayList {
    public static void main(String[] args) {
        ArrayList<String> cidades = new ArrayList<>();
        cidades.add("São Paulo");
        cidades.add("Rio de Janeiro");
        cidades.add("Belo Horizonte");
        cidades.add("Salvador");

        // Forma 1: For tradicional com índice
        System.out.println("Forma 1: For tradicional");
        for (int i = 0; i < cidades.size(); i++) {
            System.out.println(i + ": " + cidades.get(i));
        }

        // Forma 2: For-each
        System.out.println("Forma 2: For-each");
        for (String cidade : cidades) {
            System.out.println("- " + cidade);
        }

        // Forma 3: forEach com lambda (Java 8+)
        System.out.println("Forma 3: forEach lambda");
        cidades.forEach(cidade -> System.out.println("* " + cidade));
    }
}

Forma 1: For tradicional

0: São Paulo

1: Rio de Janeiro

2: Belo Horizonte

3: Salvador

Forma 2: For-each

- São Paulo

- Rio de Janeiro

- Belo Horizonte

- Salvador

Forma 3: forEach lambda

* São Paulo

* Rio de Janeiro

* Belo Horizonte

* Salvador

Operações Básicas com ArrayList

Vamos explorar as operações mais comuns:

import java.util.ArrayList;

public class OperacoesArrayList {
    public static void main(String[] args) {
        ArrayList<String> linguagens = new ArrayList<>();

        // 1. Adicionar elementos
        linguagens.add("Java");
        linguagens.add("Python");
        linguagens.add("JavaScript");
        System.out.println("Após adicionar: " + linguagens);

        // 2. Adicionar em posição específica
        linguagens.add(1, "C++");
        System.out.println("Após add(1, C++): " + linguagens);

        // 3. Acessar elemento
        String primeira = linguagens.get(0);
        System.out.println("Primeira linguagem: " + primeira);

        // 4. Modificar elemento
        linguagens.set(2, "Ruby");
        System.out.println("Após modificar índice 2: " + linguagens);

        // 5. Remover elemento pelo valor
        linguagens.remove("Ruby");
        System.out.println("Após remover Ruby: " + linguagens);

        // 6. Remover por índice
        linguagens.remove(0);
        System.out.println("Após remover índice 0: " + linguagens);

        // 7. Verificar se contém
        boolean temPython = linguagens.contains("Python");
        System.out.println("Contém Python? " + temPython);

        // 8. Tamanho
        System.out.println("Tamanho: " + linguagens.size());

        // 9. Verificar se está vazio
        System.out.println("Está vazio? " + linguagens.isEmpty());
    }
}

Após adicionar: [Java, Python, JavaScript]

Após add(1, C++): [Java, C++, Python, JavaScript]

Primeira linguagem: Java

Após modificar índice 2: [Java, C++, Ruby, JavaScript]

Após remover Ruby: [Java, C++, JavaScript]

Após remover índice 0: [C++, JavaScript]

Contém Python? false

Tamanho: 2

Está vazio? false

Quando Usar Array ou ArrayList?

Use Array [] quando:

Use ArrayList quando:

Exercícios

Teste seus conhecimentos sobre ArrayList versus Array, tipos wrapper e o diamond operator em Java:

1. Qual é a principal diferença entre Array e ArrayList?

2. Qual é a sintaxe correta para criar um ArrayList de Strings?

3. Como adicionar um elemento ao ArrayList chamado nomes?

4. Como obter o tamanho de um ArrayList chamado lista?

5. Por que não podemos usar ArrayList<int>?

6. Qual é a classe wrapper correta para armazenar valores char em um ArrayList?

7. O que é autoboxing no contexto de ArrayList?

8. Qual declaração abaixo causa erro de compilação por uso incorreto do diamond operator <>?

Exercícios de Aplicação AFF Education

Reforce o conteúdo desta aula com mais dois exercícios práticos:

1. Qual a principal vantagem do ArrayList sobre o array [] tradicional?

2. Por que um ArrayList usa Integer em vez de int?