Перейти к основному содержимому

Генерация случайного значения из перечисления

· 3 мин. чтения

1. Обзор

В этом уроке мы узнаем, как сгенерировать случайное значение из перечисления .

2. Случайное значение Enum со статическим методом

Во- первых, мы создадим статическую функцию, которая возвращает случайно сгенерированное значение из определенного набора перечислений . Значения Enum представляют собой набор констант; тем не менее, мы все еще можем объявлять статические методы в теле класса enum . Мы будем использовать статический метод в качестве помощника для генерации случайного значения перечисления .

Мы объявляем метод внутри тела класса перечисления , который является статическим и возвращает значение перечисления . Этот метод вызовет nextInt() из объекта Random , и мы назовем этот метод randomDirection() :

public enum Direction {
EAST, WEST, SOUTH, NORTH;

private static final Random PRNG = new Random();

public static Direction randomDirection() {
Direction[] directions = values();
return directions[PRNG.nextInt(directions.length)];
}
}

Внутри randomDirection() мы вызываем метод nextInt() с целочисленным аргументом. Метод nextInt() возвращает случайное число для доступа к массиву направлений ; поэтому нам нужно убедиться, что целое число не выходит за границы массива, передав связанный аргумент в nextInt() . Связанный аргумент — это общее количество направлений, которое , как мы знаем, не превысит размер массива.

Кроме того, метод values() создает копию значений перечисления каждый раз, когда вызывается метод randomDirection() . Мы могли бы улучшить производительность, создав окончательный список переменных-членов, к которому мы обращаемся после создания случайного индекса:

private static final Direction[] directions = values();

Теперь метод randomDirection() будет выглядеть следующим образом:

public static Direction randomDirection() { 
return directions[PRNG.nextInt(directions.length)];
}

Наконец, мы можем сгенерировать случайное направление , вызвав метод:

Direction direction = Direction.randomDirection();

3. Случайное значение Enum с обобщениями

Точно так же мы можем использовать дженерики для генерации случайного значения перечисления . Используя дженерики, мы создаем класс, который принимает любой тип данных перечисления для генерации случайного значения:

public class RandomEnumGenerator<T extends Enum<T>> {
private static final Random PRNG = new Random();
private final T[] values;

public RandomEnumGenerator(Class<T> e) {
values = e.getEnumConstants();
}

public T randomEnum() {
return values[PRNG.nextInt(values.length)];
}
}

Обратите внимание, как метод randomEnum() напоминает метод randomDirection() из предыдущего примера. Разница в том, что класс RandomEnumGenerator имеет конструктор, который ожидает тип перечисления, из которого можно получить постоянные значения.

Мы могли бы сгенерировать случайное направление, используя класс RandomEnumGenerator следующим образом:

RandomEnumGenerator reg = new RandomEnumGenerator(Direction.class);
Direction direction = (Direction) reg.randomEnum();

Здесь мы используем класс перечисления Direction из предыдущего раздела. RandomEnumGenerator принимает этот класс, и объект направления будет ссылаться на одно из постоянных значений класса Direction .

4. Вывод

В этом уроке мы узнали, как получить случайное значение из перечисления . Мы рассмотрели два способа сделать это: во-первых, мы используем статический метод внутри класса перечисления , который генерирует случайное значение, строго ограниченное классом перечисления , в котором объявлен метод. Кроме того, мы увидели, как можно повысить производительность за счет кэширования постоянных значений. Наконец, мы используем Generics, используя класс, который принимает любой тип перечисления , чтобы получить случайное значение.

Как всегда, полные примеры кода для этой статьи можно найти на GitHub .