1

假设我们有:

private List<Item> items = new ArrayList<Item>();

我的自定义类在哪里Item,它可以有两种状态(布尔值)活动(真)或非活动(假)它有isActive()返回当前状态的布尔值。

现在我要做的是从列表中接收随机项目,(from 0 to items.size() - 1)但它必须处于活动状态。

我想做的是在从列表中获取随机项目后,检查它是否处于活动状态,如果没有,重复直到我们收到活动项目,如果它处于活动状态,则返回它以便我们可以使用它。

不确定它是否正确,谢谢。

4

5 回答 5

6

我对您建议的方法的问题是,在某些情况下它可能会变得非常低效,特别是当您的列表中只有很少的 active 时Item。另一个想法是创建一个新列表,其中包含列表中所有活动的Item索引items

List<Integer> indexes = new ArrayList<Integer>(items.size());

for (int i = 0; i < items.size(); i++)
    if (items.get(i).isActive())
        indexes.add(i);

然后,您只需要一个来自 的随机元素,并在该特定位置indexes引用Itemin 。items所以你的随机活动元素将是

items.get(indexes.get((int)(Math.random() * indexes.size())))
于 2013-03-22T12:29:05.350 回答
1

这取决于活动和非活动项目之间的比率。如果预计大多数项目都处于活动状态,那么请按照您的想法进行,否则您可以采用 ARS 的解决方案。

笔记:

重试方法有一个警告。如果所有项目都处于非活动状态,您将最终陷入无限循环。

于 2013-03-22T12:34:10.283 回答
1

我认为它可以通过遍历列表并将所有活动项目收集到一个新列表中来为您提供更多控制。

private List<Item> activeItems = new ArrayList<Item>();

foreach (Item x in items)
{
    if (x.Isactive) activeItems.Add(x);  
}

一旦你得到了只有活动项目的列表,就从该列表中获取一个随机位置。

于 2013-03-22T12:36:44.030 回答
0

您可以扩展ArrayList和创建一个方法,该方法仅返回一个新的ArrayList(或其他Collection可能的)活动项目。

类 MyItemArrayList 扩展 ArrayList {

公共 ArrayList getActiveItems() {

ArrayList<Item> activeArrayList = new ArrayList<>();

for (Item item : this) {

    if (item.isActive()) {
        activeArrayList.add(item);
    }
}



   return activeArrayList;


 }
}
于 2013-03-22T12:36:36.173 回答
0

试试这个:

    List<CustomClass> list = new ArrayList<CustomClass>();


    Random random = new Random();


    while (true) {
        int nextInt = random.nextInt();
        if (nextInt > 0 && nextInt <= list.size()) {
            if(list.get(nextInt).isActive()){
                // Current state is active
                System.out.println("Found active");
                break;
            }
        }
    }
于 2013-03-22T12:37:59.490 回答