2013-03-22 69 views
1

獲取活動對象假設我們有:從列表

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

其中Item是我的自定義類,它可以有兩種狀態(布爾)活動狀態(true)或不活動(假)它具有布爾isActive()這返回當前狀態。

現在我所要做的,是從列表(from 0 to items.size() - 1)收到隨機項目,但它必須是積極的。

我在想什麼做的是從列表中隨機獲得物品後,檢查其激活,如果沒有,重複,直到我們收到積極的項目,如果它的活躍,返回,所以我們可以使用它。

不知道它的正確的方法,謝謝。

+0

聽起來就像是正確的做法。你有一些代碼可以分享嗎? – Farlan 2013-03-22 12:27:11

回答

6

我提出的建議方法存在的問題是,它在某些條件下會變得非常低效,特別是當您的列表中有很少活動的Item s時。另一個想法是創建一個包含所有活動Item S的的指標在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一個隨機元素,並會參考Itemitems在那個特定的位置。所以你隨機有源元件將

items.get(indexes.get((int)(Math.random() * indexes.size()))) 
1

這取決於有效和無效的項目之間的比率。 如果預計大部分項目都是主動的,那麼就去看看你的想法,否則你就可以選擇A.R.S的解決方案。

注:

有一個與重試的做法告誡。如果所有項目都處於不活動狀態,則會以無限循環結束。

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; 


} 
} 
1

我認爲這將讓你通過列表​​迭代,並收集所有活動項目進入一個新的列表更多的控制。

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

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

一旦您獲得了只有活動項目的列表,從該列表中獲取一個隨機位置。

+1

雖然我很喜歡ARS的更好的解決方案,如列表他正在創建最有可能具有較低的內存開銷。 – 2013-03-22 12:39:48

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