Printing an object that holds a list
System.out.println(shelf) calls the shelf's toString (module 18). For an object that holds a list, the list belongs in that text too. The shortest way joins the list itself to the text:
public String toString() {
return this.room + ": " + this.books;
}
The list writes itself out in brackets, with each book's own toString and commas between them: Hallway: [Emma by Austen, 474 pages, Dracula by Stoker, 418 pages]. That's hard to read when the books' texts have commas of their own. A loop gives you full control over the text.
Building the text in a loop
This toString starts with the room and the number of books, and then adds each book on a line of its own:
public class Main {
public static void main(String[] args) {
Bookshelf shelf = new Bookshelf("Living room");
shelf.add(new Book("Emma", "Austen", 474));
shelf.add(new Book("Persuasion", "Austen", 249));
shelf.add(new Book("Dracula", "Stoker", 418));
System.out.println(shelf);
Bookshelf empty = new Bookshelf("Hallway");
System.out.println(empty);
}
}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 String toString() {
if (this.books.isEmpty()) {
return this.room + ": no books";
}
String text = this.room + ": " + this.books.size() + " books";
for (Book book : this.books) {
text = text + "\n" + book;
}
return text;
}
}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 toString() {
return this.title + " by " + this.author + ", " + this.pages + " pages";
}
}Living room: 3 books
Emma by Austen, 474 pages
Persuasion by Austen, 249 pages
Dracula by Stoker, 418 pages
Hallway: no books- You met
\nin module 20: inside a String, it's a line break. A String can hold several lines, and printing it prints each of them on its own line. textstarts as the first line, and each round of the loop adds a line break and one book.+ bookcalls the book's own toString.- The line break goes before each book, not after it, so the text doesn't end with an empty line.
printlnadds the last line break itself. - An empty shelf gets its own text, checked first with
isEmpty(). Without that check it would sayHallway: 0 books, which is fine too. What an empty object says is part of designing the class.
toString only builds the text and returns it; it doesn't print anything. The caller decides what to do with it: System.out.println(shelf) prints it, and "Found: " + shelf makes a longer String of it.