Java Arena
Step 3 of 9

Methods that go through the list

An object's methods can do anything with its list that code in main could: go through it with a loop, look for a value, count things. Here the recipe gets two more methods:

Main.java
public class Main {
    public static void main(String[] args) {
        Recipe soup = new Recipe("Tomato soup");
        soup.addIngredient("tomatoes");
        soup.addIngredient("onion");
        soup.addIngredient("salt");
        soup.printIngredients();
        System.out.println(soup.needs("onion"));
        System.out.println(soup.needs("milk"));
    }
}
Recipe.java
import java.util.ArrayList;

public class Recipe {
    private String name;
    private ArrayList<String> ingredients;

    public Recipe(String name) {
        this.name = name;
        this.ingredients = new ArrayList<>();
    }

    public void addIngredient(String ingredient) {
        this.ingredients.add(ingredient);
    }

    public void printIngredients() {
        System.out.println(this.name + ":");
        for (String ingredient : this.ingredients) {
            System.out.println("- " + ingredient);
        }
    }

    public boolean needs(String ingredient) {
        return this.ingredients.contains(ingredient);
    }
}
Output
Tomato soup:
- tomatoes
- onion
- salt
true
false
  • for (String ingredient : this.ingredients) goes through the recipe's own list. It's the loop you know from main; only the list is now this.ingredients.
  • printIngredients is void: it prints, and returns nothing. It prints the recipe's name first, because a method can use all of its object's instance variables together.
  • needs passes the question on to the list. contains goes through the list for you and compares with equals (module 23), so it finds "onion" however the String was made.

A method with its own name, such as needs, also says what the question means for a recipe. soup.needs("onion") reads better than a list call in main, and main doesn't need to know that the ingredients are kept in a list at all.

A loop of your own

contains answers one question: is this exact value on the list? For any other question, write the loop yourself. This method tells whether any ingredient has a word in it, so that needsAny("cheese") is true for a recipe with goat cheese:

public boolean needsAny(String word) {
    for (String ingredient : this.ingredients) {
        if (ingredient.contains(word)) {
            return true;
        }
    }
    return false;
}

Here ingredient.contains(word) is the String method from module 16: it looks for the word inside one ingredient's name. For a pie with goat cheese and spinach, needsAny("cheese") is true, while needs("cheese") is false, since no ingredient is exactly cheese. The return true in the loop ends the method as soon as one ingredient matches, and return false after the loop runs only when none did (module 11).

Your task

Challenge 1 of 3

A garden keeps a list of the plants that grow in it. Garden.java has the list and the method plant(String name). Write two more methods in it:

  • print() prints each plant on a line of its own, starting with * .
  • grows(String name) returns true when that plant is in the garden.

The check runs:

Garden garden = new Garden();
garden.plant("rose");
garden.plant("mint");
garden.plant("fern");
garden.print();
System.out.println(garden.grows("mint"));
System.out.println(garden.grows("oak"));

and expects:

* rose
* mint
* fern
true
false

Challenge 2

What does this program print? Look at which contains each method uses: the list's, or the String's.

Challenge 3

A guestbook keeps a name for every visit, so the same name can be in it many times. Guestbook.java has the list and the method sign(String name). Write two more methods:

  • visits(String name) returns how many times the name is in the guestbook. contains can't count, so go through the list yourself, and compare the names with equals.
  • printNames() prints every name once, in the order of their first visits.

The check runs:

Guestbook book = new Guestbook();
book.sign("Ada");
book.sign("Leo");
book.sign("Ada");
book.sign("Mia");
book.sign("Ada");
System.out.println(book.visits("Ada") + " " + book.visits("Leo") + " " + book.visits("Zed"));
book.printNames();

and expects:

3 1 0
Ada
Leo
Mia