for (int i = 0; i < books.size(); i++) { Book book = books.get(i); // do something with book }This is quite error prone, because there are several places it is possible to make a mistake. For example, is the first element stored at place 0 or place 1? Should i be less than the books.size() or less or equal than the books.size()? Also, the loop will never terminate if one forgets to icrement i.
A somewhat better solution is, to use an iterator.
for (Iterator it = books.iterator(); it.hasNext(); ) { Book book = it.next(); // do something with bookHowever, the solution is still rather verbose and contains possibilities for errors.
The recommended way to iterate over a list is:
for (Book book : books) { // do something with book }The solution is very simple an elegant and there is not much opportunity to make a mistake.
Java 8 has introduced lambda expressions, which means one can now use more advanced features on collections and can also easily introduce new types of iterators oneself. A bascic for-loop can be now written as the following:
books.stream().forEach( b -> { /* do something */ });However, streams have more advanced features than just iterating over a list, e.g., there are methods to select only the elements one wants to have. Consider an implementation of a findBook(String name) operation in Java 7.public Book findBook(String name) { for (Book book : books) { if (book.getName().equals(name)) { return book; } } return null; }versus an implementation in Java 8:public Book findBook(String name) { Optional r = books .stream() .filter(b -> b.getName().equals(name)) .findFirst(); return r.isPresent() ? r.get() : null; }
Hubert Baumeister April 23, 2018
Part of Collections