В каких случаях следует идти через Collection, а в каких через Iterator? (особенно если надо просто пробежаться всем элементам).
Зависит от объекта, по которому вы хотите просто пробежаться. Если он имплементирует интерфейс Iterable (или унаследованный от него Collection), то
for(Pet p:pets) - ваш вариант.
Через Iterator следует идти, если вы хотите пробежаться по элементам и в
процессе пробежки удалить какие-то элементы из итерируемой коллекции. Сделать это безопасно можно только через Iterator.
Решение с Iterator выглядит привлекательно при написании класса, в котором реализация интерфейса Collection затруднена или непрактична.
Здесь автор имеет ввиду, если вы сами пишете класс, по которому можно "пробежаться". В этом случае проще всего сделать это через итератор, так как в нем меньше методов, которые необходимо реализовать, по сравнению с интерфейсом Collection.