programing tip

열거 형에서 임의의 값을 선택 하시겠습니까?

itbloger 2020. 6. 14. 11:02
반응형

열거 형에서 임의의 값을 선택 하시겠습니까?


내가 이와 같은 열거 형을 가지고 있다면 :

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

무작위로 하나를 선택하는 가장 좋은 방법은 무엇입니까? 생산 품질의 방탄 일 필요는 없지만 상당히 고른 분포가 좋을 것입니다.

나는 이런 식으로 할 수 있습니다

private Letter randomLetter() {
    int pick = new Random().nextInt(Letter.values().length);
    return Letter.values()[pick];
}

그러나 더 좋은 방법이 있습니까? 나는 이것이 이전에 해결 된 것 같은 느낌이 든다.


내가 제안하는 유일한 것은 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));
  }
}

단일 임의의 열거 형에 필요한 모든 방법은 다음과 같습니다.

    public static <T extends Enum<?>> T randomEnum(Class<T> clazz){
        int x = random.nextInt(clazz.getEnumConstants().length);
        return clazz.getEnumConstants()[x];
    }

사용할 것 :

randomEnum(MyEnum.class);

또한 SecureRandom 을 다음과 같이 사용하는 것을 선호합니다 .

private static final SecureRandom random = new SecureRandom();

의 제안을 결합 클리 터스헬리오스를 ,

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>>.


Single line

return Letter.values()[new Random().nextInt(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)];
  }
}

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

Here a version that uses shuffle and streams

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

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

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

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

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

참고URL : https://stackoverflow.com/questions/1972392/pick-a-random-value-from-an-enum

반응형