[java] Pick a random value from an enum?

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.

This question is related to java random enums

The answer is


Here a version that uses shuffle and streams

List<Direction> letters = Arrays.asList(Direction.values());
Collections.shuffle(letters);
return letters.stream().findFirst().get();

Simple Kotlin Solution

MyEnum.values().random()

random() is a default extension function included in base Kotlin on the Collection object. Kotlin Documentation Link

If you'd like to simplify it with an extension function, try this:

inline fun <reified T : Enum<T>> random(): T = enumValues<T>().random()

// Then call
random<MyEnum>()

To make it static on your enum class. Make sure to import my.package.random in your enum file

MyEnum.randomValue()

// Add this to your enum class
companion object {
    fun randomValue(): MyEnum {
        return random()
    }
}

If you need to do it from an instance of the enum, try this extension

inline fun <reified T : Enum<T>> T.random() = enumValues<T>().random()

// Then call
MyEnum.VALUE.random() // or myEnumVal.random() 

Letter lettre = Letter.values()[(int)(Math.random()*Letter.values().length)];

Agree with Stphen C & helios. Better way to fetch random element from Enum is:

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)];
  }
}

If you do this for testing you could use Quickcheck (this is a Java port I've been working on).

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 specification where plain TDD works with scenarios.


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());

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 SecureRandom as:

private static final SecureRandom random = new SecureRandom();

I guess that this single-line-return method is efficient enough to be used in such a simple job:

public enum Day {
    SUNDAY,
    MONDAY,
    THURSDAY,
    WEDNESDAY,
    TUESDAY,
    FRIDAY;

    public static Day getRandom() {
        return values()[(int) (Math.random() * values().length)];
    }

    public static void main(String[] args) {
        System.out.println(Day.getRandom());
    }
}

I would use this:

private static Random random = new Random();

public Object getRandomFromEnum(Class<? extends Enum<?>> clazz) {
    return clazz.values()[random.nextInt(clazz.values().length)];
}

Single line

return Letter.values()[new Random().nextInt(Letter.values().length)];

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();
}

This is probably the most concise way of achieving your goal.All you need to do is to call Letter.getRandom() and you will get a random enum letter.

public enum Letter {
    A,
    B,
    C,
    //...

    public static Letter getRandom() {
        return values()[(int) (Math.random() * values().length)];
    }
}

Combining the suggestions of cletus and 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>>.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to random

How can I get a random number in Kotlin? scikit-learn random state in splitting dataset Random number between 0 and 1 in python In python, what is the difference between random.uniform() and random.random()? Generate random colors (RGB) Random state (Pseudo-random number) in Scikit learn How does one generate a random number in Apple's Swift language? How to generate a random string of a fixed length in Go? Generate 'n' unique random numbers within a range What does random.sample() method in python do?

Examples related to enums

Enums in Javascript with ES6 Check if value exists in enum in TypeScript Why Python 3.6.1 throws AttributeError: module 'enum' has no attribute 'IntFlag'? TypeScript enum to object array How can I loop through enum values for display in radio buttons? How to get all values from python enum class? Get enum values as List of String in Java 8 enum to string in modern C++11 / C++14 / C++17 and future C++20 Implementing Singleton with an Enum (in Java) Swift: Convert enum value to String?