Java 从枚举中选择一个随机值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1972392/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pick a random value from an enum?
提问by Nick Heiner
If I have an enum like this:
如果我有这样的枚举:
public enum Letter {
A,
B,
C,
//...
}
What is the best way to pick one randomly? It doesn't need to be production quality bulletproof, but a fairly even distribution would be nice.
随机选择一个的最佳方法是什么?它不需要是生产质量的防弹,但相当均匀的分布会很好。
I could do something like this
我可以做这样的事情
private Letter randomLetter() {
int pick = new Random().nextInt(Letter.values().length);
return Letter.values()[pick];
}
But is there a better way? I feel like this is something that's been solved before.
但是有更好的方法吗?我觉得这是以前已经解决的问题。
采纳答案by cletus
The only thing I would suggest is caching the result of values()
because each call copies an array. Also, don't create a Random
every time. Keep one. Other than that what you're doing is fine. So:
我唯一建议的是缓存结果,values()
因为每次调用都会复制一个数组。另外,不要Random
每次都创建一个。留一个。除此之外,你在做什么都很好。所以:
public enum Letter {
A,
B,
C,
//...
private static final List<Letter> VALUES =
Collections.unmodifiableList(Arrays.asList(values()));
private static final int SIZE = VALUES.size();
private static final Random RANDOM = new Random();
public static Letter randomLetter() {
return VALUES.get(RANDOM.nextInt(SIZE));
}
}
回答by trashgod
Combining the suggestions of cletusand helios,
import java.util.Random;
public class EnumTest {
private enum Season { WINTER, SPRING, SUMMER, FALL }
private static final RandomEnum<Season> r =
new RandomEnum<Season>(Season.class);
public static void main(String[] args) {
System.out.println(r.random());
}
private static class RandomEnum<E extends Enum<E>> {
private static final Random RND = new Random();
private final E[] values;
public RandomEnum(Class<E> token) {
values = token.getEnumConstants();
}
public E random() {
return values[RND.nextInt(values.length)];
}
}
}
Edit: Oops, I forgot the bounded type parameter, <E extends Enum<E>>
.
编辑:糟糕,我忘记了有界类型参数<E extends Enum<E>>
.
回答by Thomas Jung
If you do this for testing you could use Quickcheck(this is a Java port I've been working on).
如果您这样做是为了测试,您可以使用Quickcheck(这是我一直在研究的 Java 端口)。
import static net.java.quickcheck.generator.PrimitiveGeneratorSamples.*;
TimeUnit anyEnumValue = anyEnumValue(TimeUnit.class); //one value
It supports all primitive types, type composition, collections, different distribution functions, bounds etc. It has support for runners executing multiple values:
它支持所有原始类型、类型组合、集合、不同的分布函数、边界等。它支持运行器执行多个值:
import static net.java.quickcheck.generator.PrimitiveGeneratorsIterables.*;
for(TimeUnit timeUnit : someEnumValues(TimeUnit.class)){
//..test multiple values
}
The advantage of Quickcheck is that you can define tests based on a specificationwhere plain TDD works with scenarios.
Quickcheck 的优点是您可以根据规范定义测试,其中纯 TDD 与场景配合使用。
回答by anonymous
Letter lettre = Letter.values()[(int)(Math.random()*Letter.values().length)];
回答by Eldelshell
A single method is all you need for all your random enums:
所有随机枚举只需要一个方法:
public static <T extends Enum<?>> T randomEnum(Class<T> clazz){
int x = random.nextInt(clazz.getEnumConstants().length);
return clazz.getEnumConstants()[x];
}
Which you'll use:
您将使用:
randomEnum(MyEnum.class);
I also prefer to use SecureRandomas:
我也更喜欢使用SecureRandom作为:
private static final SecureRandom random = new SecureRandom();
回答by Joseph Thomson
It's probably easiest to have a function to pick a random value from an array. This is more generic, and is straightforward to call.
使用函数从数组中选择随机值可能是最简单的。这是更通用的,并且可以直接调用。
<T> T randomValue(T[] values) {
return values[mRandom.nextInt(values.length)];
}
Call like so:
像这样调用:
MyEnum value = randomValue(MyEnum.values());
回答by Folea
It′s eaiser to implement an random function on the enum.
在枚举上实现随机函数更容易。
public enum Via {
A, B;
public static Via viaAleatoria(){
Via[] vias = Via.values();
Random generator = new Random();
return vias[generator.nextInt(vias.length)];
}
}
and then you call it from the class you need it like this
然后你从你需要它的类中调用它
public class Guardia{
private Via viaActiva;
public Guardia(){
viaActiva = Via.viaAleatoria();
}
回答by Deepti
Agree with Stphen C & helios. Better way to fetch random element from Enum is:
同意 Stphen C & helios 的观点。从 Enum 获取随机元素的更好方法是:
public enum Letter {
A,
B,
C,
//...
private static final Letter[] VALUES = values();
private static final int SIZE = VALUES.length;
private static final Random RANDOM = new Random();
public static Letter getRandomLetter() {
return VALUES[RANDOM.nextInt(SIZE)];
}
}
回答by Mohamed Taher Alrefaie
Single line
单线
return Letter.values()[new Random().nextInt(Letter.values().length)];
回答by major seitan
Here a version that uses shuffle and streams
这是一个使用 shuffle 和流的版本
List<Direction> letters = Arrays.asList(Direction.values());
Collections.shuffle(letters);
return letters.stream().findFirst().get();