最近,我决定深入研究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) {
...
}