Números Aleatórios em Java – A Classe java.util.Random

Veja neste artigo um guia rápido para a geração de diferentes tipos de séries de números aleatórios em Java com o uso da classe Random (pacote java.util).

Introdução

Os números aleatórios são utilizados de diversas formas em programas de computador. Eles são importantes no desenvolvimento de jogos, na área de segurança de informações (ex: para gerar senhas ou textos de campos captcha) e em programas de mineração de dados e análise estatística, apenas para citar alguns exemplos.

A linguagem Java disponibiliza funcionalidades para a geração de números aleatórios em uma classe denominada “Random” do pacote “java.util”. Este artigo apresenta um guia rápido dos usos mais comuns da classe Random.

A Classe Random na Prática

As instâncias da classe “Random” são objetos geradores de números aleatórios, que produzem estes números em resposta a solicitações. A Listagem 1 apresenta um exemplo básico de utilização da classe. A explicação do programa se encontra logo após a especificação do código.

Listagem 1: Exemplo básico de utilização da classe Random.
import java.util.Random; public class Random1 { public static void main(String[] args) { //instância um objeto da classe Random usando o construtor padrão Random gerador = new Random(); //imprime sequência de 10 números inteiros aleatórios for (int i = 0; i < 10; i++) { System.out.println(gerador.nextInt()); } } }

Um resultado possível para a execução do programa é mostrado na Figura 1.

Figura 1: Execução do programa da Listagem 1.

Agora vamos à explicação do programa. A classe “Random” está definida no pacote “java.util”, portanto qualquer programa Java que faça uso da mesma precisará fazer a importação com “import java.util.random”. No programa da Listagem 1, o gerador de número aleatórios foi instanciado através do uso do construtor padrão: Random gerador = new Random().

Esta é a forma mais simples de inicializar um objeto da classe Random. De acordo com a documentação da classe, quando se utiliza o construtor padrão, o valor desemente utilizado em cada chamada será “muito provavelmente” diferente do valor de semente escolhido em qualquer invocação posterior desse construtor. A grosso modo, a semente pode ser definida uma espécie de “ponto de partida” para a geração de uma sequência de números aleatórios (em exemplos posteriores mostraremos como é possível especificar uma semente). O programa contém um loop for que gera 10 números aleatórios através de 10 chamadas ao método “nextInt”. No exemplo, o método é chamado sem nenhum parâmetro, retornando a cada iteração um inteiro diferente da sequência de aleatórios. Serão retornados números positivos ou negativos dentre toda a faixa de valores inteiros do Java.

O resumo é o seguinte: todas as vezes que você executar o programa da Listagem 1, obterá uma sequência diferente de 10 números inteiros negativos ou positivos. O menor e o maior número que podem ser gerados são, respectivamente, iguais ao menor e maior inteiro possível na plataforma em que o programa estiver sendo executado.

No entanto, para muitas aplicações práticas você precisará gerar inteiros entre 0 e algum limite superior (ex: 10, 50, 100, etc.). Para fazer isto, basta fazer uma chamada ao método “nextInt” passando um parâmetro “n”. Neste caso, o inteiro a ser retornado estará contido na faixa de 0 a n-1. A Listagem 2 mostra um exemplo de programa que retorna uma sequência de 10 números que sempre possuirão valor entre 0 e 25.

Listagem 2: Gerando sequência de números aleatórios inteiros com valores entre 0 e 25.
import java.util.Random; public class Random2 { public static void main(String[] args) { //instância um objeto da classe Random usando o construtor básico Random gerador = new Random(); //imprime sequência de 10 números inteiros aleatórios entre 0 e 25 for (int i = 0; i < 10; i++) { System.out.println(gerador.nextInt(26)); } } }

Um resultado possível para a execução deste exemplo é mostrado na Figura 2.

Figura 2: Execução do programa da Listagem 2.

Nos exemplos das Listagens 1 e 2, a sequência de números retornada será sempre diferente a cada execução do programa, pois estamos utilizando o construtor default (sem parâmetros) da classe “Random”. As sequências são diferentes porque quando se usa o construtor default, o Java escolhe “por conta própria” uma semente diferente a cada execução.

Entretanto, também é possível gerar sequências fixas, bastando para isso fornecer a sua própria semente. Isto é feito no exemplo da Listagem 3, onde a semente especificada é “19700621”.

Listagem 3: Especificando a semente.
import java.util.Random; public class Random3 { public static void main(String[] args) { //instância um objeto da classe Random especificando a semente Random gerador = new Random(19700621); //imprime sequência de 10 números inteiros aleatórios entre 0 e 25 for (int i = 0; i < 10; i++) { System.out.println(gerador.nextInt(26)); } } }

Neste caso, o programa sempre gerará os mesmos 10 números para a sequência a cada execução (Figura 3).

Figura 3: Execução do programa da Listagem 3.

A classe “Random” também fornece métodos para a geração de números reais: nextDouble() e nextFloat(). Estes métodos não aceitam parâmetros, sempre gerando números entre 0 e 1. A Listagem 4 apresenta um exemplo de utilização. No exemplo, a semente não é especificada, porém isso poderia ser feito sem problemas.

Listagem 4: Números reais.
import java.util.Random; public class RandomReal { public static void main(String[] args) { Random r = new Random(); System.out.println(r.nextDouble()); System.out.println(r.nextFloat()); } }

Um exemplo de resultado possível é apresentado na Figura 4.

Figura 4: Execução do programa da Listagem 4.

A seguir apresentamos algumas dicas que poderão ser úteis em situações práticas.

Dica 1: suponha que você precise gerar um número aleatório entre 1 e 6 (ex: para simular um jogo de dados). Se você simplesmente usar o método nextInt(6), obterá números entre 0 e 5, algo que você não deseja. Resolver a situação é simples, bastando aplicar o seguinte recurso: int numDado = gerador.nextInt(6) + 1.

Dica 2: Imagine que você precise gerar um número real qualquer entre 0 e 90, por exemplo. Vimos que os métodos “nextDouble” e “nextFloat” retornam sempre números entre 0 e 1. Então como podemos resolver a situação? A resposta é simples, basta multiplicar o número gerado por 90! double numReal = gerador.nextDouble() * 90.

Dica 3: Essa é para o pessoal que trabalha com Estatística. Em todos os exemplos apresentados, os números reais e inteiros foram selecionados considerando uma distribuição uniforme sobre uma faixa de valores. No entanto, também é possível gerar números aleatórios a partir de uma distribuição gaussiana, com o uso do método “nextGaussian”. Este método não possui parâmetros e retorna um número aleatório considerando uma distribuição normal com média 0 e desvio padrão 1. Para estes valores de média e desvio padrão, cerca de 70% dos números gerados estarão na faixa de -1 a 1 e cerca de 95% entre -2 e 2. double numReal = gerador.nextGaussian().

Dica 4: Além de números inteiros e reais, a classe “Random” também pode gerar booleanos: boolean resultado = gerador.nextBoolean().

Conclusão

Este artigo realizou uma breve introdução à classe Random. Através dela, é possível gerar diversos tipos distintos de números aleatórios e nem todos foram aqui apresentados. Para obter informações adicionais, consulte.


Confira também

Artigos relacionados