最近,我决定深入研究Java,并在个人项目中使用Java。最后我编写了一个类,以从加权值列表中选择一个随机值。

我要做的第一件事是编写一个接口IWeighable,它只有一个方法:

double getWeight();


因此,我想使用该随机化器选择的每个类都必须实现这样的接口,以便能够获得选项的权重值。

现在,这是我直到最近才写的内容(现在尝试进行改进):

public IWeighable getRandomWeighable(List<IWeighable> weighables)
{
    double totalWeight = 0.0;

    for (IWeighable weighable : weighables)
    {
        if (weighable.getWeight() > 0)
            totalWeight += weighable.getWeight();
    }

    double selected = SRandom.randDouble() * totalWeight;

    for (IWeighable weighable : weighables)
    {
        double weight = weighable.getWeight();
        selected -= weight;

        if (selected <= 0)
            return weighable;
    }

    return null;
}


但是我刚刚意识到,这可能不是编码的最佳方法。为什么?因为例如,如果我编写实现“ IWeighable”的类“ Encounter”,则不能简单地调用:

List<Encounter> encounters;
...
Encounter rEncounter = WeightedRandomizer.getInstance().getRandomWeighable(encounters);


因为“遇到”不是List <IWeighable>类型。

我尝试将“ getRandomWeighable”的签名更改为:

public IWeighable getRandomWeighable(List<Class<? extends IWeighable>> weighables) {


但这需要大量的泛型工作,我很满意,但是它们会引发各种异常,这是我希望在特定代码中避免的事情。我觉得有一种更轻松,更好的方式来编写此代码,我正努力寻找它。

有小费吗?

亲切的问候,并感谢您的帮助

编辑

抱歉,我只是想了一下,然后尝试将getRandomWeighable签名更改为:

public <T extends IWeighable> T getRandomWeighable(List<T> weighables)


我正在考虑删除此问题,但可能对像我这样的另一个Java新手很有用,所以不确定。

最佳答案

如果您的目标是接受具有实现IWeighable的泛型类型的任何列表,则可以使用Upper Bounded Wildcard List<? extends IWeighable>

public IWeighable getRandomWeighable(List<? extends IWeighable> weighables) {
  ...
}

09-25 20:17