Java Arena
Step 8 of 9

Finding an object on the list

A method can also go through the list to find one object and return it: the largest, or the first one that matches. Its return type is then the class of the objects. When there's nothing to return, it returns null, "no object" (module 22):

Main.java
public class Main {
    public static void main(String[] args) {
        Bookshelf shelf = new Bookshelf("Study");
        shelf.add(new Book("Emma", "Austen", 474));
        shelf.add(new Book("Kindred", "Butler", 264));
        shelf.add(new Book("Middlemarch", "Eliot", 880));
        System.out.println("Thickest: " + shelf.thickest());
        Book found = shelf.find("Kindred");
        if (found != null) {
            System.out.println("Found it, by " + found.getAuthor());
        }
        if (shelf.find("Ulysses") == null) {
            System.out.println("No Ulysses here");
        }
        Bookshelf hall = new Bookshelf("Hallway");
        System.out.println(hall.thickest());
    }
}
Bookshelf.java
import java.util.ArrayList;

public class Bookshelf {
    private String room;
    private ArrayList<Book> books;

    public Bookshelf(String room) {
        this.room = room;
        this.books = new ArrayList<>();
    }

    public void add(Book book) {
        this.books.add(book);
    }

    public Book thickest() {
        if (this.books.isEmpty()) {
            return null;
        }
        Book thickest = this.books.get(0);
        for (Book book : this.books) {
            if (book.getPages() > thickest.getPages()) {
                thickest = book;
            }
        }
        return thickest;
    }

    public Book find(String title) {
        for (Book book : this.books) {
            if (book.getTitle().equals(title)) {
                return book;
            }
        }
        return null;
    }
}
Book.java
public class Book {
    private String title;
    private String author;
    private int pages;

    public Book(String title, String author, int pages) {
        this.title = title;
        this.author = author;
        this.pages = pages;
    }

    public String getTitle() {
        return this.title;
    }

    public String getAuthor() {
        return this.author;
    }

    public int getPages() {
        return this.pages;
    }

    public String toString() {
        return this.title + " by " + this.author + ", " + this.pages + " pages";
    }
}
Output
Thickest: Middlemarch by Eliot, 880 pages
Found it, by Butler
No Ulysses here
null
  • thickest keeps the thickest book so far in a local variable of type Book, starting with the first book on the list. Each book with more pages takes its place. This is module 13's search for the largest value, with objects: the pages decide, but the whole Book is kept.
  • Starting from this.books.get(0) needs a first book, so the empty check comes first. Without it, get(0) on an empty list would crash with an IndexOutOfBoundsException.
  • With >, a book takes the kept one's place only when it's thicker, so of two equally thick books, the first one wins. With >=, the last one would.
  • find returns the book as soon as it finds it, which also ends the loop. return null after the loop runs only when no book matched.

Checking the result

A method that may return null puts a job on its caller: check before using the result. found.getAuthor() would crash with a NullPointerException if found were null, so main checks found != null first. Printing a null is fine, though: System.out.println(hall.thickest()) prints null.

The method returns the object itself, not a copy. shelf.find("Emma") == shelf.find("Emma") is true: both calls return a reference to the one Book on the shelf. So if Book could change, a change made through the returned reference would change the book on the shelf.

Your task

Challenge 1 of 3

A hotel keeps a list of its rooms. Room.java is ready: a room has a number and a number of beds, with the getter getBeds(). In Hotel.java, write the method findRoom(int people): it returns the first room on the list with at least that many beds, or null when there's no such room. The check runs:

Hotel hotel = new Hotel();
hotel.add(new Room(101, 1));
hotel.add(new Room(102, 2));
hotel.add(new Room(201, 4));
System.out.println(hotel.findRoom(2));
System.out.println(hotel.findRoom(3));
System.out.println(hotel.findRoom(5));

and expects:

Room 102, 2 beds
Room 201, 4 beds
null

Challenge 2

What does this program print? find and oldest both return a Horse from the stable's list, or null.

Challenge 3

An election has a list of candidates. Candidate.java is ready: a candidate has a name and a number of votes that starts at 0, with getName(), getVotes() and addVote(). In Election.java, write two methods:

  • vote(String name) gives one vote to the candidate with that name. A name that isn't a candidate's does nothing.
  • leader() returns the candidate with the most votes. When there are no candidates, or when two or more share the most votes, there's no leader, and it returns null.

The check runs:

Election election = new Election();
election.add(new Candidate("Ines"));
election.add(new Candidate("Omar"));
election.add(new Candidate("Yuki"));
System.out.println(election.leader());
election.vote("Omar");
election.vote("Ines");
election.vote("Omar");
election.vote("Zed");
System.out.println(election.leader());

and expects:

null
Omar, 2 votes