Java 当每个人都有不同的概率时,如何选择随机枚举?

Java 当每个人都有不同的概率时,如何选择随机枚举?,java,random,enums,Java,Random,Enums,我知道在stackoverflow中已经有一个关于如何随机选择枚举的问题。在示例代码中,每个字母都具有相同的被选中概率。但是当不是每个枚举都有相同的概率时,我该如何重写代码呢?例如:A的概率为50%,B的概率为30%,C的概率为15%,D的概率为5% public enum Letter { A, B, C, D; private static final List<Letter> VALUES = Collections.unmodifiableLis

我知道在stackoverflow中已经有一个关于如何随机选择枚举的问题。在示例代码中,每个字母都具有相同的被选中概率。但是当不是每个枚举都有相同的概率时,我该如何重写代码呢?例如:A的概率为50%,B的概率为30%,C的概率为15%,D的概率为5%

public enum Letter {
  A,
  B,
  C,
  D;

  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));
  }
}
公开枚举信{
A.
B
C
D
私有静态最终列表值=
Collections.unmodifiableList(Arrays.asList(values());
私有静态最终int SIZE=VALUES.SIZE();
私有静态最终随机=新随机();
公共静态信函{
返回值.get(RANDOM.nextInt(SIZE));
}
}
可以帮助您

具体来说,这幅图:

在您的示例中,在
0
99
之间选择一个数字
x

  • x<50
    =>A获胜
  • 50b胜
  • 80c获胜
  • 95d获胜

这是一种将每个枚举值与概率范围相关联的方法,然后在该范围内拟合一个随机数以选择一个值:

enum Letter {
    A(0, 51), B(51, 81), C(81, 96), D(95, 101);

    private int probStart;
    private int probEnd;

    private static final Random RANDOM = new Random();

    Letter(int s, int e) {
        this.probStart = s;
        this.probEnd = e;
    }

    public static Letter randomLetter() {
        int pick = RANDOM.nextInt(100);
        return Arrays.stream(values())
                .filter(v -> pick >= v.probStart && pick < v.probEnd)
                .findAny()
                .get();
    }
}

制作一个长度为20的数组,在其中放入1 D、3 C、6 B和10 A。然后得到一个从0到19的随机数,并得到一个具有此索引的数组元素。这很容易出错,因为开发人员必须确保范围是连续的,没有间隙和重叠。。。更安全的做法是只存储每个枚举的权重,然后在内部计算所有范围和最大值。也就是说,
A(50)、B(30)、C(15)、D(5)
@joachimsuer是的,让值声明概率肯定不容易出错,但同一类(开发人员)将负责规范化probabilities@ernest_k谢谢你的帮助!一个问题:为什么0和51之间存在差距,而不是0和50,或者1和51(95和101之间是一样的)?
{A=56, B=26, C=14, D=4}
{A=39, B=39, C=18, D=4}
{A=51, B=30, C=13, D=6}