Java Behavioral Design Patterns – Iterator Design Pattern
Iterator Design Pattern is one of the Behavioural design patterns in Java. It is used for traversing through the collection of data in a particular class.
This pattern hides the actual implementation of traversal through the collection. The application programs just use iterator methods for different purposes. Iterator pattern allows accessing the elements of a collection object in a sequential manner without knowledge of its structure. Key points to remember about this interface are:
- This pattern is used when you foresee a collection is traversed with different types of criteria.
- The collection object should be accessed and traversed without exposing its data structure.
- New traversal operations should be defined for collection object without changing its interface.
<Here are ALL other Java Design Patterns, explained in detail with examples>
Iterator Design Pattern by Example
To understand we will consider a simple example of BookService. We will also implement a custom iterator which will traverse based on the publisher of the book.
First things first, let us define our iterator interface.
1 2 3 4 5 6 |
public interface BookIterator { public boolean hasMore(); public Book next(); } |
Our custom iterator interface has 2 methods. One will determine if there are any more elements to traverse. The other method next() will give us actual element.
As we are iterating over books, we will define simple POJO as:
1 2 3 4 5 6 7 |
public class Book { private String name; private String publication; //Constructor; Getters; Setters; } |
Our base classes are ready, let’s define BookService and its custom iterator:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
public class BookService { private List<Book> books; public BookIterator getIterator(String publication) { return new BookIteratorImpl(books, publication); } private class BookIteratorImpl implements BookIterator { private String publicationCheck; private List<Book> listOfBooks; private int index; public BookIteratorImpl(List<Book> books, String pubCheck) { this.listOfBooks = books; this.publicationCheck = pubCheck; } @Override public boolean hasMore() { while(index < listOfBooks.size()) { Book buk = this.listOfBooks.get(index); if(buk.getPublication().equalsIgnoreCase(publicationCheck)) { return true; } else { index++; } } return false; } @Override public Book next() { Book buk = this.listOfBooks.get(index); index++; return buk; } } public BookService() { books = new ArrayList<Book>(); } public List<Book> getBooks() { return books; } public void setBooks(List<Book> books) { this.books = books; } } |
Please note that this custom iterator is specific to this type of collection. Hence we have added that as a private class to our main class.
The custom iterator accepts publisher name to check and iterate over only books of that publisher.
Running the example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
public class IteratorPatternDemo { public static void main(String[] args) { List<Book> books = new ArrayList<Book>(); books.add(new Book("Java", "Pub A")); books.add(new Book("C++", "Pub B")); books.add(new Book("PHP", "Pub A")); books.add(new Book("Kotlin", "Pub B")); books.add(new Book("Kafka", "Pub A")); books.add(new Book("Salesforce", "Pub C")); BookService bs = new BookService(); bs.getBooks().addAll(books); System.out.println("List of Books from Publisher B"); BookIterator bi = bs.getIterator("Pub C"); while (bi.hasMore()) { Book b = bi.next(); System.out.println("--> " + b); } System.out.println("\nList of Books from Publisher B"); bi = bs.getIterator("Pub B"); while (bi.hasMore()) { Book b = bi.next(); System.out.println("--> " + b); } } } |
During our test run, we have prepared a list of few books and trying to iterate over them. The output:
1 2 3 4 5 6 |
List of Books from Publisher C --> Book[Salesforce,Pub C] List of Books from Publisher B --> Book[C++,Pub B] --> Book[Kotlin,Pub B] |
Advantages:
- Iterator design pattern hides the actual implementation of traversal through the collection and client programs just use iterator methods.
- The iterator pattern can be implemented in a customized way in Java according to need.
- We can use several iterators on the same collection.
Conclusion
So it was fairly simple to understand Iterator Design Pattern. Please feel free to ask a question or comment.
You can download the code from our GitHub repository:
Download from Git
<Here are ALL other Java Design Patterns, explained in detail with examples>