Java Arena
Step 2 of 5

Objects from the user's input

The objects in a list don't have to be written into the program. A loop can read what the user types and create an object from each line. Here the user types tasks, one per line, and an empty line when there are no more:

Main.java
import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        ArrayList<Task> tasks = new ArrayList<>();

        while (true) {
            String description = scanner.nextLine();
            if (description.isEmpty()) {
                break;
            }
            tasks.add(new Task(description));
        }

        tasks.get(0).markDone();
        System.out.println(tasks.size() + " tasks");
        for (Task task : tasks) {
            System.out.println(task);
        }
    }
}
Task.java
public class Task {
    private String description;
    private boolean done;

    public Task(String description) {
        this.description = description;
        this.done = false;
    }

    public void markDone() {
        this.done = true;
    }

    public String toString() {
        if (this.done) {
            return "[x] " + this.description;
        }
        return "[ ] " + this.description;
    }
}
Input
water the plants
call the dentist
buy stamps
(an empty line)
Output
3 tasks
[x] water the plants
[ ] call the dentist
[ ] buy stamps
  • The loop is the while (true) loop you know: read a line, stop at the empty line, and otherwise use the line.
  • new Task(description) creates a new object in every round, and add puts it in the list. The variable description lasts only one round, but the list still refers to every object.
  • tasks.get(0).markDone() changes the first object in the list. Like the list variables in module 14, the list refers to its objects: nothing is copied, so tasks.get(0) is the very task that was added, and the change shows when the list is printed. (With no tasks at all, get(0) would crash; a real program would check tasks.isEmpty() first.)

Check before you create

The if with break comes before new Task(...). If add came first, the empty line would become a task of its own: the list would end with a task that has no description, and the count would be one too high.

Input that ends with an empty line

The input of a program like this one ends with an empty line: that's what stops the loop. The task cards show it as "(an empty line)". When you run such a program with your own input, end it with an empty line too. If the input runs out before it, nextLine() has nothing left to read and the program stops with an error.

Your task

Challenge 1 of 3

NameTag.java is ready. Read names until an empty line. For each name, create a NameTag and add it to the list tags. Then print the number of tags, followed by name tags, and every tag with a for-each loop. For the input Ines, Tom and an empty line, the program prints:

2 name tags
Hello, my name is Ines
Hello, my name is Tom

Challenge 2

Racers sign up for a race by name, and each one gets the next start number: the first racer gets 1, the second 2, and so on. Racer.java is ready. Read names until an empty line, create a Racer for each name with its start number, and add it to the list racers. Then print every racer. For the input Ines, Tom, Mia and an empty line, the program prints:

#1 Ines
#2 Tom
#3 Mia

Challenge 3

This program should read wishes until an empty line, then print how many there are and each one. But for the input a bike, a kite and an empty line, it says 3 wishes, and its last line is I wish for with nothing after it. Fix it, so the program prints:

2 wishes
I wish for a bike
I wish for a kite