ArrayList Loop Patterns


Assume we have a list of menu items:

ArrayList<MenuItem> itemList = new ArrayList<MenuItem>();
That has been filled with items.

Process All Items

The most common thing to do with a list, is to do something with every item in the list like print it, or add it to a sum.

We can use a traditional for loop:

    // We have filled itemList.  Let's see what the items are.
    System.out.println("Printing all the items:");
    for ( int i = 0; i < itemList.size(); i++ )
    {
        MenuItem oneItem = itemList.get(i);
        System.out.println("\t" + oneItem.toString());  // tab + item info
    } 

Or we can use the for-each style for loop, that is built specifically for stepping through collections like an ArrayList.

    System.out.println("\nPrinting all the items again using a different loop:");
    for ( MenuItem oneItem : itemList )
    {
        System.out.println("\t" + oneItem.toString());  // tab + item info
    } 

Sum All Items (variation on Process-All)

    // What would it cost to buy one of everything?
    double sum = 0.0;
    for ( MenuItem oneItem : itemList )
    {
        sum += oneItem.getPrice();
    }
    System.out.println("The cost of buying 1 of everything is " + sum + ".");

Average (variation on Process-All)

    // What is the average price of menu items in the list? (use sum from above)
    double average = sum / itemList.size();
    System.out.println("The average price of things in this list is " + average);

Process Some (Subset)

Another variation is to do something with just some of the items in the list. We actually go through the whole list but test each item to see if it is the one item (or one of the several items) that we want.

Search for an Item in the List

    // Find "Tomato Caprese" (but full name is longer, so use contains)
    // Look through all the items...
    for ( MenuItem oneItem : itemList )
    {
        // Is this the one (or one of several) we're looking for?
        String itemName = oneItem.getItemName();
        if ( itemName.contains("Tomato Caprese") )
        {
            // Use toString method to print full information
            System.out.println(itemName.toString());
        }
    }

Search for Multiple Items in the List (Subset)

    // Print all the items from Saffron.
    // But also, let's put them in a new list to see what that looks like.
    ArrayList<MenuItem> allFromSaffron = new ArrayList<MenuItem>();
    System.out.println("\nItems from Saffron: ");
    for ( MenuItem oneItem : itemList )
    {
        // Use .equals rather than == to compare strings!!!
        if ( oneItem.getRestaurant().equals("Saffron") )
        {
            System.out.println("\t" + oneItem.toString());
            allFromSaffron.add(oneItem);
        }
    }

Count Items that Meet Some Criteria (Subset)

    // How many rice dishes are in the overall list?
    int numRiceDishes = 0;
    for ( MenuItem oneItem : itemList )
    {
        if ( oneItem.getItemName().contains("Rice") )
        {
            numRiceDishes++;
        }
    }
    System.out.println("\nThere are " + numRiceDishes
        + " rice dishes in this list.");

    // How many items are less than $10?
    int count = 0;
    for ( MenuItem oneItem : itemList )
    {
        if ( oneItem.getPrice() < 10.00 )
        {
            count++;
        }
    }
    System.out.println ("\nThere are " + count + " items less than $10");

Average of Subset

    // What is the average price of menu items from Saffron?
    int numFromSaffron = 0;
    double sumFromSaffron = 0.0;
    for ( MenuItem oneItem : itemList )
    {
        String rest = oneItem.getRestaurant();
        if ( rest.equals("Saffron") )
        {
            sumFromSaffron += oneItem.getPrice();
            numFromSaffron++;
        }
    }
    average = sumFromSaffron / numFromSaffron;
    System.out.println("\nThe average price of things from Saffron is " + average);
    // NOTE: we could have looped through the allFromSaffron list
    //       to get the sum and then divided by allFromSafron.size().

Search based on Multiple Criteria

    // What is the price of Chinn Chinn's fried rice?
    for ( MenuItem oneItem : itemList )
    {
        if ( oneItem.getRestaurant().equals("Chinn Chinn") &&
             oneItem.getItemName().contains("Fried Rice") )
        {
            System.out.println("The price of fried rice at Chinn Chinn is "
                + oneItem.getPrice() + ".");
        }
    }

Find Extreme (Minimum or Maximum Value)

To find a minimum or maximum value, you go through the list comparing new items to whatever minimum or maximum you have identified so far, changing to a new extreme value when you find a value that is smaller or larger (depending on which extreme you are looking for). The tricky part to this algorithm is selecting an initial candidate. One approach is to assume for the moment that the first one is the extreme value and then look for any that are more extreme. The other approach is to pick a value that is extreme in the other direction as the starting point. For example, if we're looking for the largest value in a list of positive integers, we could start by pretending that a negative number is the maximum; any value in the list will be larger than that.

Find Max (Assume First Value is the Maximum)

    // What is the most expensive item?
    // Make sure there is at least one item, or this doesn't make sense!
    if ( itemList.size() > 0 )
    {
        // Assume the first item is the most costly (at least so far).
        MenuItem costly = itemList.get(0);

        // Look through the list and see if any are more costly.
        for ( MenuItem oneItem : itemList )
        {
            if ( oneItem.getPrice() > costly.getPrice() )
            {
                // oneItem is more costly, so most costly seen (so far)
                costly = oneItem;
            }
        }
        // By the time we get here, costly is truly the most costly one.
        System.out.println("The most expensive thing in this list is "
            + costly.toString());
    }
    else
    {
        // Can't find most expensive in an empty list!
        System.out.println("There are no items in this list!");
    }

Find Max (Start with a Dummy Maximum)

    // What is the most expensive item?
    // Invent a dummy "most costly item" that is less costly than anything.
    double costlyPrice = -1.0;   // Obviously everything will be more costly.
    String costlyItemName = "";  // Don't know item name yet.
    for ( MenuItem oneItem : itemList )
    {
        if ( oneItem.getPrice() > costlyPrice )
        {
            // oneItem is more costly, so most costly seen (so far)
            costlyPrice = oneItem.getPrice();
            costlyItemName = oneItem.getItemName();
        }
    }
    // By the time we get here, costlyItemName is truly the name of
    // the most costly item.
    System.out.println("The most expensive thing in this list is "
        + costlyItemName + " at $" + costlyPrice + ".");

Find Top N Items

This code segment is more complicated, because it involves finding the most expensive, then the next most expensive (that is less than the most expensive), then …

    // What are the three most expensive items?  Create a list to put them in.
    ArrayList<MenuItem> mostExpensive = new ArrayList<MenuItem>();
    double upperBound = 100.00;   // set an initial upper bound higher than the real max
    for ( int i = 0; i < 3; i++ )
    {
        // Find the most expensive that is under the upperBound.  (Usual
        // "find max" algorithm except for the extra upperBound check.)
        double expensivePrice = -1.0;
        int numAtThisPrice = 0;
        for ( MenuItem anElement : itemList )
        {
            double thisPrice = anElement.getPrice();
            if ( thisPrice > expensivePrice && thisPrice < upperBound )
            {
                expensivePrice = thisPrice;
            }
        }
        // Now find all the elements that are at that price and add to list.
        for ( MenuItem anElement : itemList )
        {
            if ( anElement.getPrice() == expensivePrice )
            {
                mostExpensive.add(anElement);
                numAtThisPrice++;
            }
        }
        // Lower upperBound, so next time we don't find these same items again.
        upperBound = expensivePrice;

        // Tricky: i is about to go up by 1 in for loop, but maybe it
        // should go up by more than one?  Increase by 1 less than
        // numAtThisPrice so that when the loop increments i we will
        // actually have raised it by numAtThisPrice.
        if ( numAtThisPrice < 1)
            i += (numAtThisPrice - 1);
    }
    System.out.println("\nThe 3 most expensive menu items are: ");
    for ( MenuItem anElement : mostExpensive )
        System.out.println("\t" + anElement);
    System.out.println();