Como trabalhar com listas e números aleatórios em Java
Uma lista guarda vários valores em ordem, numa só variável: os nomes de uma turma, os produtos de um carrinho, as perguntas de um quiz. Cada valor ocupa uma posição, chamada de índice, que começa em 0. Com um número aleatório entre 0 e o último índice, você sorteia um elemento da lista, como num sorteio de nomes ou num jogo que escolhe uma palavra ao acaso.
Este tutorial vai das listas aos números aleatórios e termina com um sorteador de nomes que usa os dois.
Lista ou array?
O Java tem dois jeitos de guardar vários valores em sequência. O array (String[]) tem tamanho fixo: você diz quantas posições ele tem ao criar, e depois não dá para aumentar. A lista (List<String>) cresce e diminui conforme você adiciona e remove elementos, e já vem com métodos prontos para buscar, ordenar e verificar o que tem dentro. No dia a dia, as listas são mais usadas, justamente por essa flexibilidade.
Na declaração List<String>, o <String> diz o tipo dos elementos: essa lista só aceita textos. Uma lista de números inteiros seria List<Integer>. Repare que é Integer e não int: listas guardam objetos, e cada tipo primitivo tem uma classe correspondente (int vira Integer, double vira Double).
Criando uma lista
Existem três formas comuns de criar uma lista, e elas não se comportam do mesmo jeito.
List.of cria uma lista que não pode mudar: não dá para adicionar, remover nem trocar elementos.
List<String> frutas = List.of("Maçã", "Banana", "Laranja", "Morango");
Arrays.asList cria uma lista de tamanho fixo. Dá para trocar um elemento por outro, mas não dá para adicionar nem remover.
List<String> frutas = Arrays.asList("Maçã", "Banana", "Laranja", "Morango");
new ArrayList<>() cria uma lista que pode tudo: adicionar, remover e trocar elementos. Para começar com alguns valores, passe outra lista para ele:
List<String> frutas = new ArrayList<>(List.of("Maçã", "Banana", "Laranja", "Morango"));
frutas.add("Uva");
Para usar essas classes, importe no começo do arquivo: import java.util.List;, import java.util.ArrayList; e, para o Arrays.asList, import java.util.Arrays;.
Quando usar cada uma
List.of | Arrays.asList | new ArrayList<>() | |
|---|---|---|---|
| Adicionar e remover | Não | Não | Sim |
Trocar um elemento (set) | Não | Sim | Sim |
| Bom para | Listas fixas, como as opções de um menu | Código antigo, anterior ao Java 9 | Listas que mudam durante o programa |
Se você está começando, use new ArrayList<>() sempre que a lista for mudar e List.of quando ela for só para leitura.
Os métodos mais usados
List<String> frutas = new ArrayList<>(List.of("Maçã", "Banana", "Laranja"));
frutas.add("Morango"); // adiciona no fim
System.out.println(frutas.size()); // 4: quantos elementos a lista tem
System.out.println(frutas.get(0)); // Maçã: o elemento na posição 0
frutas.set(1, "Abacaxi"); // troca o elemento da posição 1
System.out.println(frutas.contains("Uva")); // false: a lista tem esse elemento?
frutas.remove("Laranja"); // remove pelo valor
frutas.remove(0); // remove pela posição
System.out.println(frutas); // [Abacaxi, Morango]
O get recebe o índice e devolve o elemento daquela posição. Como o índice começa em 0, o último elemento fica em size() - 1.
Percorrendo a lista
Percorrer uma lista é passar por cada elemento, um de cada vez, para mostrar, somar ou procurar algo. Há dois jeitos.
O for com índice anda pelas posições de 0 até o fim, e usa o get para pegar o elemento de cada uma:
for (int i = 0; i < frutas.size(); i++) {
System.out.println(i + ": " + frutas.get(i));
}
0: Maçã
1: Banana
2: Laranja
3: Morango
O for-each entrega cada elemento direto, sem índice:
for (String fruta : frutas) {
System.out.println(fruta);
}
Lido em voz alta, ele diz: “para cada fruta em frutas, mostre a fruta”. É o mais fácil de ler e o mais usado.
Use o for-each quando você só precisa dos elementos. Use o for com índice quando precisa da posição, como para numerar os itens ou comparar um elemento com o seguinte.
Gerando números aleatórios com Random
A classe Random, do pacote java.util, gera números aleatórios. Crie um objeto dela uma vez e chame os métodos sempre que precisar de um número novo:
import java.util.Random;
Random random = new Random();
int dado = random.nextInt(6) + 1; // de 1 a 6
int numero = random.nextInt(10); // de 0 a 9
boolean caraOuCoroa = random.nextBoolean(); // true ou false
O nextInt(10) devolve um número de 0 a 9: o limite que você passa nunca é sorteado. Por isso o dado soma 1, para ir de 1 a 6. A cada execução do programa, os números mudam.
A partir do Java 17, dá para passar o começo e o fim do intervalo direto: random.nextInt(1, 7) também sorteia de 1 a 6, porque o fim continua fora do sorteio.
Sorteando um elemento da lista
Para sortear um elemento, sorteie um índice e use o get:
int indice = random.nextInt(frutas.size());
String sorteada = frutas.get(indice);
O nextInt(frutas.size()) devolve um número de 0 até size() - 1, que são exatamente os índices válidos da lista. Se a lista crescer, o sorteio acompanha sem você mudar nada.
Exemplo do zero: um sorteador de nomes
Um programa que sorteia a ordem de apresentação dos trabalhos de uma turma. Ele sorteia um nome, mostra e remove esse nome da lista, para ele não sair de novo, até a lista acabar.
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Sorteador {
public static void main(String[] args) {
List<String> alunos = new ArrayList<>(List.of("Ana", "Bruno", "Carla", "Diego", "Elisa"));
Random random = new Random();
System.out.println("Ordem de apresentação:");
int posicao = 1;
while (!alunos.isEmpty()) {
int indice = random.nextInt(alunos.size());
String sorteado = alunos.remove(indice);
System.out.println(posicao + "º: " + sorteado);
posicao++;
}
}
}Uma saída possível (muda a cada execução):
Ordem de apresentação:
1º: Carla
2º: Ana
3º: Elisa
4º: Bruno
5º: Diego
Repare em três detalhes:
- A lista foi criada com
new ArrayList<>(), porque o programa remove nomes dela. ComList.of, oremovequebraria o programa. - O
remove(indice)faz duas coisas: tira o nome da lista e devolve o nome removido, que vai para a variávelsorteado. - O laço é um
while, e não umfor-each, porque a lista diminui a cada volta. OisEmpty()diz quando ela acabou.
Para testar, salve o arquivo como Sorteador.java e rode no terminal, na mesma pasta, com java Sorteador.java. Rode algumas vezes e veja a ordem mudar.