Java Arena
Step 9 of 9

Objects from a file

In the previous step, each line's values were used right away and then forgotten. When the program needs them later, each line becomes an object: a class holds one record's values together, and a list holds the objects. Reading the file then takes one loop, and after it the program answers its questions from the list:

The file trails.txt
Coast Path,14
Pine Loop,6
Ridge Walk,9
Main.java
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        ArrayList<Trail> trails = new ArrayList<>();
        try (Scanner scanner = new Scanner(Paths.get("trails.txt"))) {
            while (scanner.hasNextLine()) {
                String[] parts = scanner.nextLine().split(",");
                trails.add(new Trail(parts[0], Integer.valueOf(parts[1])));
            }
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }

        System.out.println("Trails: " + trails.size());
        System.out.println("Ten kilometers or less:");
        for (Trail trail : trails) {
            if (trail.getLength() <= 10) {
                System.out.println(trail);
            }
        }
    }
}
Trail.java
public class Trail {
    private String name;
    private int length;

    public Trail(String name, int length) {
        this.name = name;
        this.length = length;
    }

    public String getName() {
        return this.name;
    }

    public int getLength() {
        return this.length;
    }

    public String toString() {
        return this.name + " (" + this.length + " km)";
    }
}
Output
Trails: 3
Ten kilometers or less:
Pine Loop (6 km)
Ridge Walk (9 km)
  • Each line is split, and its parts go to the constructor in the order of its parameters: new Trail(parts[0], Integer.valueOf(parts[1])). The new object goes straight into the list.
  • The list is made before the try, so it's still there after it. If the file can't be read, the list simply stays empty.
  • After the loop, the file is done with. The questions (how many, which ones, the longest) are answered from the list, with the tools of module 19.

Reading in a method

A method that reads the file and returns the list keeps main short, and it can read any file of trails:

public static ArrayList<Trail> readTrails(String fileName) {
    ArrayList<Trail> trails = new ArrayList<>();
    try (Scanner scanner = new Scanner(Paths.get(fileName))) {
        while (scanner.hasNextLine()) {
            String[] parts = scanner.nextLine().split(",");
            trails.add(new Trail(parts[0], Integer.valueOf(parts[1])));
        }
    } catch (Exception e) {
        System.out.println("Error: " + e.getMessage());
    }
    return trails;
}

main then starts with ArrayList<Trail> trails = readTrails("trails.txt");.

The end of part 4

This step ends the material of the MOOC's fourth part. Part 4 was the start of object-oriented programming: you wrote classes of your own, created objects from them with constructors, gave them methods such as getters and toString, and kept many objects in a list. This module then brought in data from outside the program: files, read line by line and turned into numbers, records and objects. Classes and files together let a program work with as much data as it's given. The MOOC closes the part with a summary page on its own site, for reading only.

Your task

Challenge 1 of 3

The file plants.txt has lines such as fern,7: a plant, and how many days go by between waterings. Plant.java is ready. Complete main, so it creates a Plant from each line, adds it to the list plants, and then prints every plant. For the file shown below, it prints:

fern: water every 7 days
cactus: water every 21 days
basil: water every 2 days

Challenge 2

Recipe.java is ready. Write a method readRecipes(String fileName, ArrayList<Recipe> recipes) that reads a file of lines such as pancakes,20 (a recipe and the minutes it takes) and adds a Recipe for each of them to the list it's given. Some lines are notes with no comma, such as ask Grandma about the pie: skip them. The method returns how many lines it skipped. If the file can't be read, it prints Error: and the error's message, and returns 0.

The check makes an empty list and calls readRecipes("recipes.txt", recipes) with the file shown below. It prints what the method returned, the list's size and its first recipe:

1
3
pancakes (20 min)

Challenge 3

The file flights.txt has a line for each flight of the day, such as AY123,15: the flight's code and how many minutes late it left. Flight.java is ready. Read the flights into a list of Flight objects, and then print the number of flights, how many were more than 30 minutes late, and the flight that was the latest. The file has at least one flight; if two share the largest delay, print the first of them. For the file shown below, the program prints:

Flights: 4
Over 30 minutes late: 1
Latest: AY904 (45 min late)