Feature Java: RandomGenerator

Com a constante evolução do Java, novas funcionalidades são introduzidas para facilitar a vida dos desenvolvedores. Uma dessas adições foi o RandomGenerator
, que trouxe uma abordagem mais moderna e robusta para a geração de números aleatórios.
Introdução ao RandomGenerator
O RandomGenerator
foi introduzido no Java 17 como parte da JEP 356: Enhanced Pseudo-Random Number Generators. Esta JEP tinha como objetivo melhorar a API de geração de números aleatórios, tornando-a mais flexível e eficiente. Antes do RandomGenerator
, os desenvolvedores utilizavam a classe Random
, que embora funcional, apresentava algumas limitações e não oferecia a mesma versatilidade das novas implementações.
Principais Implementações
O RandomGenerator
é uma interface que define métodos para a geração de números aleatórios. Algumas das principais implementações dessa interface incluem:
-
Random
-
SplittableRandom
-
SecureRandom
-
ThreadLocalRandom
Cada uma dessas classes tem características próprias, adequadas para diferentes cenários de uso.
Exemplos Práticos
Exemplo 1: Gerando Números Aleatórios Simples
Vamos começar com um exemplo básico utilizando a implementação padrão Random
.
import java.util.random.RandomGenerator;
import java.util.random.RandomGeneratorFactory;
public class RandomExample {
public static void main(String[] args) {
RandomGenerator randomGenerator = RandomGeneratorFactory.of("Random").create();
// Gerando um número inteiro aleatório
int randomInt = randomGenerator.nextInt(100); // Número entre 0 e 99
System.out.println("Número inteiro aleatório: " + randomInt);
// Gerando um número real aleatório
double randomDouble = randomGenerator.nextDouble();
System.out.println("Número real aleatório: " + randomDouble);
}
}
Neste exemplo, utilizamos a fábrica RandomGeneratorFactory
que recupera do sistema todas as classes que implementam RandomGenerator
e as coloca num Map
onde a chave é o nome da classe de implementação.
Com o RandomGenerator
do tipo Random
instanciado geramos um número inteiro e um número real aleatório.
Exemplo 2: Utilizando SplittableRandom para Paralelismo
A classe SplittableRandom
é ideal para aplicações que exigem geração de números aleatórios em paralelo.
import java.util.SplittableRandom;
import java.util.random.RandomGeneratorFactory;
public class SplittableRandomExample {
public static void main(String[] args) {
SplittableRandom randomGenerator = (SplittableRandom) RandomGeneratorFactory.of("SplittableRandom").create();
// Gerando números aleatórios em paralelo
SplittableRandom splitRandom = randomGenerator.split();
int randomInt1 = randomGenerator.nextInt(100);
int randomInt2 = splitRandom.nextInt(100);
System.out.println("Número inteiro aleatório 1: " + randomInt1);
System.out.println("Número inteiro aleatório 2: " + randomInt2);
}
}
Neste exemplo, utilizamos SplittableRandom
e a capacidade de dividir a instância para gerar números aleatórios de forma paralela, o que é particularmente útil em ambientes de alta concorrência.
Exemplo 3: Segurança com SecureRandom
Para aplicações que exigem um alto nível de segurança, como geração de senhas ou tokens, a classe SecureRandom
é a escolha certa.
import java.security.SecureRandom;
import java.util.random.RandomGeneratorFactory;
public class SecureRandomExample {
public static void main(String[] args) {
SecureRandom secureRandom = (SecureRandom) RandomGeneratorFactory.of("SecureRandom").create();
// Gerando um número inteiro seguro aleatório
int secureRandomInt = secureRandom.nextInt(100);
System.out.println("Número inteiro seguro aleatório: " + secureRandomInt);
// Gerando um número real seguro aleatório
double secureRandomDouble = secureRandom.nextDouble();
System.out.println("Número real seguro aleatório: " + secureRandomDouble);
}
}
Neste exemplo, SecureRandom
é utilizado para gerar números aleatórios com um alto nível de segurança, garantindo imprevisibilidade e resistência a ataques.
Exemplo 4: Utilizando ThreadLocalRandom em Ambientes Multithreaded
A classe ThreadLocalRandom
é projetada para ser utilizada em contextos multithreaded, onde cada thread tem sua própria instância de gerador de números aleatórios, o que minimiza a contenção e melhora o desempenho.
import java.util.concurrent.ThreadLocalRandom;
public class ThreadLocalRandomExample {
public static void main(String[] args) {
// Obtendo a instância de ThreadLocalRandom
ThreadLocalRandom randomGenerator = ThreadLocalRandom.current();
// Gerando um número inteiro aleatório
int randomInt = randomGenerator.nextInt(100); // Número entre 0 e 99
System.out.println("Número inteiro aleatório: " + randomInt);
// Gerando um número real aleatório
double randomDouble = randomGenerator.nextDouble();
System.out.println("Número real aleatório: " + randomDouble);
// Gerando um número inteiro aleatório dentro de um intervalo
int randomIntRange = randomGenerator.nextInt(50, 100); // Número entre 50 e 99
System.out.println("Número inteiro aleatório no intervalo [50, 100): " + randomIntRange);
}
}
Neste exemplo, ThreadLocalRandom
é utilizado para gerar números aleatórios em um ambiente multithreaded. A obtenção da instância é feita através do método current()
, que retorna a instância do gerador de números aleatórios associada à thread atual. Utilizamos esse gerador para criar números inteiros e reais aleatórios, além de gerar números dentro de um intervalo específico.
Conclusão
O RandomGenerator
e suas diversas implementações oferecem uma API mais moderna e flexível para a geração de números aleatórios em Java. Introduzido no Java 17 através da JEP 356, ele substitui e aprimora as capacidades oferecidas pela classe Random
. Dependendo das necessidades da aplicação, você pode escolher a implementação que melhor se adapta, seja para simplicidade, paralelismo ou segurança.
Explorar essas novas funcionalidades não só torna o código mais robusto, mas também aproveita as melhorias de desempenho e segurança que vêm com as versões mais recentes do Java. Experimente utilizar o RandomGenerator
em seus projetos e veja a diferença que ele pode fazer.