Como gerar um número aleatório em Java

⚡ Resumo Inteligente

Números aleatórios em Java Elas provêm de quatro opções relacionadas da biblioteca padrão: a classe Random, Math.random, ThreadLocalRandom e SecureRandom, cada uma oferecendo uma combinação diferente de velocidade, segurança de threads e força criptográfica para aplicações reais.

  • 🎲 Classe aleatória: java.util.Random expõe nextInt, nextLong, nextDoublee nextBoolean para tipos primitivos comuns.
  • 🧮 Matemática.aleatória: Math.random retorna um número de ponto flutuante de dupla precisão entre 0.0 (inclusive) e 1.0 (exclusive), utilizando uma instância compartilhada de Random.
  • 🎯 Intervalos personalizados: Passe um limite para nextInt ou dimensione Math.random para gerar valores dentro de quaisquer limites mínimo e máximo.
  • 🧵 Segurança da rosca: O ThreadLocalRandom em java.util.concurrent atribui a cada thread seu próprio gerador e supera um Random compartilhado em situações de contenção.
  • 🔐 Segurança: A função SecureRandom do pacote java.security gera valores criptograficamente fortes para senhas, tokens e chaves de sessão.
  • ???? Reprodutibilidade: Inicializar uma variável aleatória com um valor longo fixo torna os testes e simulações determinísticos em todas as execuções.

Como gerar um número aleatório em Java

Números aleatórios aparecem em todos os lugares em Java, desde dados de testes unitários e jogos de rolagem de dados até fichas de sessão e baralhos embaralhados. Este tutorial explica como gerar números aleatórios em Java Como usar todas as opções da biblioteca padrão e escolher a mais adequada para cada tarefa.

Gerar número aleatório em Java

O Java A biblioteca padrão oferece quatro maneiras comuns de gerar um número aleatório:

  • java.util.Random é a classe de propósito geral. Ela produz valores booleanos, inteiros, longos, de ponto flutuante e de precisão dupla por meio de métodos como nextInt, nextLong e nextDouble.
  • Math.random é uma função auxiliar estática que retorna um valor double entre 0.0 (inclusive) e 1.0 (exclusive) usando uma variável compartilhada. Random internamente.
  • ThreadLocalRandom in java.util.concurrent Atribui a cada thread seu próprio gerador, de modo que várias threads não disputem uma única instância.
  • SecureRandom in java.security Gera números pseudoaleatórios criptograficamente fortes para senhas, identificadores de sessão e chaves.

As seções abaixo mostram como gerar dez números aleatórios com cada abordagem.

Exemplo: Gerar Número Aleatório Usando Java Classe Aleatória

O primeiro exemplo usa java.util.Random Para produzir dez números inteiros no intervalo de 0 a 99, inclusive:

import java.util.Random;

public class RandomNumbers {
    public static void main(String[] args) {
        Random objGenerator = new Random();
        for (int iCount = 0; iCount < 10; iCount++) {
            int randomNumber = objGenerator.nextInt(100);
            System.out.println("Random No : " + randomNumber);
        }
    }
}

Saída:

Random No : 17
Random No : 57
Random No : 73
Random No : 48
Random No : 68
Random No : 86
Random No : 34
Random No : 97
Random No : 73
Random No : 18

Uma instância de Random é criado como objGenerator. O nextInt(int bound) O método retorna um valor entre 0 (inclusive) e o limite fornecido (exclusive), portanto nextInt(100) produz valores de 0 a 99. Para tornar a sequência reproduzível, passe uma semente para o construtor, por exemplo new Random(42)A mesma semente sempre produz a mesma sequência, o que é útil em testes e simulações.

Exemplo: Usando Java Matemática.aleatória

Para gerar dez valores aleatórios no intervalo de 0.0 a 1.0, chame a função estática. Math.random método dentro de um laçoEsta é a maneira mais rápida de obter um número de ponto flutuante de dupla precisão aleatório sem criar um objeto gerador:

public class DemoRandom {
    public static void main(String[] args) {
        for (int xCount = 0; xCount < 10; xCount++) {
            System.out.println(Math.random());
        }
    }
}

Saída:

0.46518450373334297
0.14859851177803485
0.5628391820492477
0.6323378498048606
0.1740198445692248
0.9140544122258946
0.9167350036262347
0.49251219841030147
0.7426056725722353
0.2039418871298877

Sob o capô, Math.random cria uma única estática Random na primeira utilização e chamadas nextDouble sobre isso. Esse gerador único compartilhado funciona bem para demonstrações, mas torna-se um gargalo sob carga multithread pesada, o que será abordado nas próximas seções.

Gere um número aleatório em um intervalo personalizado.

Programas reais geralmente precisam de um valor aleatório dentro de um intervalo específico, como um número inteiro entre 1 e 6 para o lançamento de um dado ou um número decimal entre 10.0 e 20.0 para uma simulação. Dois padrões abrangem quase todos os casos.

Número inteiro aleatório entre min e max (inclusive):

import java.util.Random;

public class RangeDemo {
    public static void main(String[] args) {
        Random rnd = new Random();
        int min = 1;
        int max = 6;
        // nextInt(max - min + 1) returns 0..(max-min), then shift by min
        int dice = rnd.nextInt(max - min + 1) + min;
        System.out.println("Dice roll : " + dice);
    }
}

Número aleatório de dois valores entre mínimo e máximo:

double min = 10.0;
double max = 20.0;
double value = min + (max - min) * Math.random();
System.out.println("Value : " + value);

Ambos os padrões funcionam pegando um valor do intervalo nativo do gerador, escalando-o para a largura do intervalo de destino e deslocando-o para cima pelo valor mínimo. Se você estiver em Java 8 ou posterior, o mesmo resultado está disponível através da versão mais recente. ints, longs e doubles métodos de fluxo em Random, Por exemplo rnd.ints(10, 1, 7).forEach(System.out::println) para dez lançamentos de dados.

ThreadLocalRandom para Multithreading Code

Um único compartilhado Random É thread-safe, mas lento sob contenção, pois cada thread precisa sincronizar com a mesma semente interna. ThreadLocalRandom, adicionado em Java 7 e morando em java.util.concurrent, atribui a cada thread seu próprio gerador, de modo que não haja disputa de bloqueio.

import java.util.concurrent.ThreadLocalRandom;

public class ThreadLocalDemo {
    public static void main(String[] args) {
        // random int in [1, 100]
        int i = ThreadLocalRandom.current().nextInt(1, 101);

        // random long in [1000, 5000]
        long l = ThreadLocalRandom.current().nextLong(1000L, 5001L);

        // random double in [0.0, 1.0)
        double d = ThreadLocalRandom.current().nextDouble();

        System.out.println(i + " " + l + " " + d);
    }
}

Uso ThreadLocalRandom.current() dentro de threads de trabalho, fluxos paralelos e qualquer tarefa concorrente. Observe que setSeed lança UnsupportedOperationExceptionPortanto, o uso de sementes para fins de reprodutibilidade não é suportado; se você precisar de uma semente fixa, use uma semente simples. Random.

SecureRandom para aleatoriedade sensível à segurança Numbers

Instâncias de Random e ThreadLocalRandom não são criptograficamente seguros. Com algumas amostras de saída, um atacante pode reconstruir o estado interno e prever valores futuros. Para senhas, tokens de sessão, valores de salt e chaves criptográficas, use java.security.SecureRandom Em vez disso, ele extrai material inicial do conjunto de entropia do sistema operacional e produz valores que resistem à previsão.

import java.security.SecureRandom;

public class SecureDemo {
    public static void main(String[] args) {
        SecureRandom secure = new SecureRandom();

        byte[] token = new byte[16];
        secure.nextBytes(token);          // 128-bit random token

        int otp = secure.nextInt(1_000_000); // 6-digit one-time code

        System.out.println("OTP : " + String.format("%06d", otp));
    }
}

SecureRandom é mais lento que Random Porque utiliza algoritmos mais robustos e material inicial mais rico. Reserve-o para trabalhos de segurança e utilize os geradores mais rápidos para jogos, simulações e dados de teste.

Perguntas Frequentes

Crie uma instância de java.util.Random e chame nextInt, nextLong, next.Doubleou nextBoolean. Para uma solução rápida em uma única linha, use Math.random, que retorna um número de ponto flutuante entre 0.0 e 1.0. Ambas as abordagens são fornecidas com a biblioteca padrão.

Chame random.nextInt(max – min + 1) + min para números inteiros, ou min + (max – min) * Math.random() para números de ponto flutuante de dupla precisão. As fórmulas dimensionam o intervalo do gerador para a sua janela de destino e deslocam o valor pelo valor mínimo.

Random é uma classe completa com métodos para diversos tipos primitivos e suporta inicialização (seeding). Math.random é uma função auxiliar estática que retorna um número de ponto flutuante (double) entre 0.0 e 1.0. Internamente, Math.random chama uma única instância compartilhada de Random.

Sim, mas chamadas simultâneas disputam a mesma semente interna, o que torna o código com muitas threads mais lento. Use `ThreadLocalRandom.current()` da classe `java.util.concurrent` para atribuir a cada thread seu próprio gerador e eliminar essa disputa.

Passe um valor long fixo para o construtor Random, por exemplo, new Random(42), ou chame setSeed(42). O gerador produzirá a mesma sequência a cada execução, o que é essencial para testes e simulações repetíveis.

Use SecureRandom sempre que o valor precisar resistir à previsibilidade, como senhas, tokens de sessão, valores de salt, códigos de uso único e chaves criptográficas. O Random simples é rápido, mas previsível, portanto, não é seguro para aplicações de segurança.

Os frameworks de aprendizado de máquina usam geradores pseudoaleatórios para inicializar os pesos, embaralhar os dados de treinamento e dividir os conjuntos de validação. Fixar uma semente torna os experimentos reproduzíveis, permitindo que as equipes comparem execuções de modelos e depurem resultados de forma confiável.

Sim. O GitHub Copilot cria snippets para Random, ThreadLocalRandom e SecureRandom, com fórmulas de dimensionamento de intervalo correspondentes, e JUnit testes. RevAnalise cada sugestão para confirmar se a classe escolhida se adequa ao caso de uso, especialmente para código sensível à segurança.

Resuma esta postagem com: