问题
如果我有这样的枚举:
public enum Letter {
A,
B,
C,
//...
}
随机选择一个的最佳方法是什么?它不需要是生产质量的防弹,但相当均匀的分布将是不错的。
我可以做这样的事情
private Letter randomLetter() {
int pick = new Random().nextInt(Letter.values().length);
return Letter.values()[pick];
}
但有更好的方法吗?我觉得这是以前已经解决的问题。
#1 热门回答(114 赞)
我唯一建议的是缓存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));
}
}
#2 热门回答(87 赞)
所有随机枚举都需要一种方法:
public static <T extends Enum<?>> T randomEnum(Class<T> clazz){
int x = random.nextInt(clazz.getEnumConstants().length);
return clazz.getEnumConstants()[x];
}
你将使用哪个:
randomEnum(MyEnum.class);
我也更喜欢使用SecureRandomas:
private static final SecureRandom random = new SecureRandom();
#3 热门回答(37 赞)
结合cletus和2889489083的建议,
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)];
}
}
}
编辑:哎呀,我忘了有界类型参数,<E extends Enum<E>>
。