Se eu tenho um enum como este:
public enum Letter {
A,
B,
C,
//...
}
Qual é a melhor maneira de escolher uma aleatoriamente? Não precisa ser à prova de balas com qualidade de produção, mas uma distribuição bastante uniforme seria boa.
Eu poderia fazer algo assim
private Letter randomLetter() {
int pick = new Random().nextInt(Letter.values().length);
return Letter.values()[pick];
}
Mas existe uma maneira melhor? Eu sinto que isso é algo que já foi resolvido antes.
Letter.values()
para criar uma nova cópia daLetter
matriz de valor interno .Respostas:
A única coisa que eu sugeriria é armazenar em cache o resultado
values()
porque cada chamada copia uma matriz. Além disso, não crieRandom
sempre. Mantenha um. Fora isso, o que você está fazendo está bem. Assim:fonte
values()
matriz em uma lista não modificável. OVALUES
objeto já está encapsulado em virtude de ser declaradoprivate
. Seria mais simples e mais eficiente fazê-loprivate static final Letter[] VALUES = ...
.Um único método é tudo o que você precisa para todas as suas enumerações aleatórias:
Que você usará:
Também prefiro usar o SecureRandom como:
fonte
Combinando as sugestões de cletus e helios ,
Edit: Opa, esqueci o parâmetro do tipo delimitado
<E extends Enum<E>>
,.fonte
E extends Enum<E>
?new RandomEnum<>(Season.class)
é permitido desde Java 7.RandomEnum
classe única seria legal como uma micro biblioteca, se você quisesse agrupá-la e publicá-la na central.Única linha
fonte
Concordo com Stphen C & helios. A melhor maneira de buscar o elemento aleatório do Enum é:
fonte
fonte
Esta é provavelmente a maneira mais concisa de atingir seu objetivo. Tudo o que você precisa fazer é ligar
Letter.getRandom()
e você receberá uma carta enum aleatória.fonte
Provavelmente é mais fácil ter uma função para escolher um valor aleatório de uma matriz. Isso é mais genérico e é fácil de chamar.
Ligue assim:
fonte
Aqui uma versão que usa shuffle e streams
fonte
Solução Kotlin simples
random()
é uma função de extensão padrão incluída no Kotlin base noCollection
objeto. Link da documentação do KotlinSe você deseja simplificá-lo com uma função de extensão, tente o seguinte:
Para torná-lo estático na sua classe enum. Certifique-se de importar
my.package.random
no seu arquivo enumSe você precisar fazer isso a partir de uma instância da enum, tente esta extensão
fonte
Se você fizer isso para testar, poderá usar o Quickcheck ( esta é uma porta Java em que estou trabalhando ).
Ele suporta todos os tipos primitivos, composição de tipos, coleções, diferentes funções de distribuição, limites etc. Tem suporte para corredores executando vários valores:
A vantagem do Quickcheck é que você pode definir testes com base em uma especificação em que o TDD comum trabalha com cenários.
fonte
É ansioso para implementar uma função aleatória no enum.
e então você chama da classe que você precisa assim
fonte
Eu usaria isso:
fonte
Eu acho que esse método de retorno de linha única é eficiente o suficiente para ser usado em um trabalho tão simples:
fonte