Atenção, já vou deixar claro que não quero gerar um Random ok?
O problema é o seguinte:
Digamos que eu tenha 4 números (2,5,7,9)
Eu apenas quero escolher um desses números randomicamente.
Eu pensei em fazer um random entre 1 e 10, se o numero gerado nao for algum desses 4, eu gero o rand novamente, porém existe a possibilidade de eu ficar no loop por muito tempo…
[code]//Crie uma lista com os números
List<Integer> numeros = new ArrayList<Integer>();
numeros.add(2);
numeros.add(5);
numeros.add(7);
numeros.add(9);
//Embaralhe a lista
Collections.shuffle(numeros);
//Agora é só pegar os números
System.out.println(numeros.get(0));[/code]
A vantagem do método acima é que você pode eliminar o número de índice 0 da lista. E assim, o próximo zero não se repetirá. Bem prático caso você queira fazer um programa de sorteio da mega-sena.
O método nextInt(int n) da classe Random sorteia um número inteiro entre 0 e (n - 1). No exemplo acima, o método sorteará um número entre 0 e o tamanho da lista - 1 (4 - 1).
O ideal é não fazer new Random() inline, como você fez. Isso não garante a geração de números aleatórios caso o método seja chamado várias vezes seguidas, num for, por exemplo. Faça você mesmo o teste:
[code]public void gerarNumero() {
List numeros = new ArrayList();
numeros.add(2);
numeros.add(5);
numeros.add(7);
numeros.add(9);
public static void main(String[] args) {
for (int i = 0; i < 100; i++)
gerarNumero();
}
[/code]
Para corrigir, retira-se o Random para fora do método, e só inicializa ele uma única vez:
public static final Random RANDOM = new Random();
public void gerarNumero() {
List<Integer> numeros = new ArrayList<Integer>();
numeros.add(2);
numeros.add(5);
numeros.add(7);
numeros.add(9);
System.out.println(numeros.get(RANDOM.nextInt(numeros.size())));
}
O ideal é não fazer new Random() inline, como você fez. Isso não garante a geração de números aleatórios caso o método seja chamado várias vezes seguidas, num for, por exemplo. Faça você mesmo o teste:
(…)
[/code]
Para corrigir, retira-se o Random para fora do método, e só inicializa ele uma única vez:
(...)
[/quote]
Até por questão de evitar a criação de vários objetos desnecessariamnete, sua sugestão é válida. Sempre utilizo essa abordagem.
Quanto a várias instâncias gerarem os números aleatórios, você sabe se por exemplo, em duas chamadas consecutivas, é possível que o seed do Random seja o mesmo currentTimeMillis?
[quote=felipealbuquerque]Até por questão de evitar a criação de vários objetos desnecessariamnete, sua sugestão é válida. Sempre utilizo essa abordagem.
Quanto a várias instâncias gerarem os números aleatórios, você sabe se por exemplo, em duas chamadas consecutivas, é possível que o seed do Random seja o mesmo currentTimeMillis?[/quote]
Se as camadas forem criadas simultaneamente, sim. Mas isso geralmente é difícil de acontecer. Se não quiser contar com isso, você pode definir na mão um offset para cada random:
public void Random random = new Random(System.currentTimeMillis() + offset);
Onde offset é um número qualquer como -1, 1, 2, 3, diferente para cada camada.
Normalmente eu prefiro ter um único gerador Random, e definido estaticamente ainda por cima. Ou seja:
import java.security.SecureRandom;
...
private static Random r = new SecureRandom();
...
Isso não dá problemas relacionados a ficar criando instâncias de Random que são inicializadas com o mesmo valor de semente (que no caso é System.currentTimeMillis(), um valor que no Windows tem precisão de apenas 10 milissegundos ou ainda mais inexato.)
Entretanto, em alguns sistemas operacionais, SecureRandom “prende” um pouco a execução de seu programa. Por exemplo, em um Linux ele é implementado em termos de /dev/rand ou /dev/random (não tenho certeza), e esse “device” é um bocadinho lento ao ser inicializado. No Windows, é implementado em termos de CryptGenerateRandom (não lembro mais o nome da API), e essa implementação depende do provider da CryptoAPI - às vezes é gerado por hardware, se algum driver de algum dispositivo criptográfico estiver instalado. Aí ele também pode “prender” um pouco a execução.