Matthewek
Matthewek

Reputation: 1559

Get active objects from list

Lets say we have:

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

where Item is my custom class, which can have two states (boolean) active (true) or not active (false) it has boolean isActive() which returns current state.

Now what I am trying to do, is to receive random item from the list (from 0 to items.size() - 1) but it has to be active.

What I was thinking to do is to after getting random item from the list, check if its active, and if not, repeat till we receive active item, if its active, return it so we can use it.

Not sure if its right approach, thanks.

Upvotes: 1

Views: 837

Answers (5)

arshajii
arshajii

Reputation: 129537

The problem I have with your suggested approach is that it can become very inefficient under certain conditions, particularly when you have very few active Items in your list. Another idea would be to create a new list containing the indexes of all of the active Items in the items list:

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

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

Then you simply need a random element from indexes, and would refer to the Item in items at that particular location. So your random active element would be

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

Upvotes: 6

Parrish Husband
Parrish Husband

Reputation: 3178

I think it would give you more control by iterating through the list and collecting all active Items into a new list.

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

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

Once you've got the list of only active items, get a random position from that list.

Upvotes: 1

Ankur Shanbhag
Ankur Shanbhag

Reputation: 7804

Try this out :

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

Upvotes: 0

Jean Waghetti
Jean Waghetti

Reputation: 4727

You can extend ArrayList and create a method that returns a new ArrayList (or other Collection maybe) only with active items.

class MyItemArrayList extends ArrayList {

public ArrayList getActiveItems() {

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

for (Item item : this) {

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



   return activeArrayList;


 }
}

Upvotes: 0

Klas Lindb&#228;ck
Klas Lindb&#228;ck

Reputation: 33283

That depends on the ratio between active and inactive items. If most items are expected to be active, then go with your idea, otherwise you can go woth A.R.S' solution.

Note:

There is a caveat with the retry approach. If all items are inactive you will end up with an infinite loop.

Upvotes: 1

Related Questions