Уже не в первый раз вижу в задачах подобный код. Есть некая коллекция экземпляров нашего класса. В данном случае это LinkedList<Book>. Добавляем в этот список два объекта:
List<Book> books = new LinkedList<Book>();
books.add(new Book("Tom Sawyer"));
books.add(new Book("Hercule Poirot"));
В классе Book авторы задачи переопределили метод toString() — теперь он выводит результат работы функции, возвращающей объект String:
static class Book {
    public String toString() {
        return getOutputByBookType();
    }

    private String getOutputByBookType() {
        //...
        return output;
    }
}
В результате System.out.println(books) выводит результат работы getOutputByBookType() для каждого элемента коллекции через запятую с пробелом:
System.out.println(books);
// [Tom Sawyer was written by Mark Twain, Agatha Christie: Hercule Poirot is a detective]
А собственно как и почему это работает? Мы же передаём в println() объект типа LinkedList. Но при этом выводится каждый элемент этого LinkedList, да ещё и через запятую с пробелом. При этом переопределяем мы вроде бы Object.toString, в котором я ничего подобного не нахожу. Сразу скажу, что пробовал обращаться к гуглу, но ответа на этот вопрос не нашёл. Короче говоря, что мы всё-таки переопределяем и почему оно работает?