DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Composite Design Pattern in Java
  • Object Relational Behavioral Design Patterns in Java
  • Distribution Design Patterns in Java - Data Transfer Object (DTO) And Remote Facade Design Patterns
  • Context Object Design Pattern in Java: Introduction and Key Points

Trending

  • The 4 R’s of Pipeline Reliability: Designing Data Systems That Last
  • Unlocking AI Coding Assistants Part 1: Real-World Use Cases
  • Java's Quiet Revolution: Thriving in the Serverless Kubernetes Era
  • Evolution of Cloud Services for MCP/A2A Protocols in AI Agents
  1. DZone
  2. Coding
  3. Languages
  4. Iterator Design Pattern In Java

Iterator Design Pattern In Java

By 
Brijesh Saxena user avatar
Brijesh Saxena
DZone Core CORE ·
Oct. 12, 20 · Tutorial
Likes (5)
Comment
Save
Tweet
Share
11.5K Views

Join the DZone community and get the full member experience.

Join For Free

Today, I will discuss a relatively simple and very commonly used behavioral design pattern called — Iterator Design Pattern. Iterator Pattern provides a simple way to iterate through the collection of objects.

Iterator Design Pattern

  • The Iterator Design Pattern is one of twenty-three well known GoF design patterns  provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation. 
  • Iterator Design Pattern provides an Iterator object to traverse a collection/container and access its member objects.
  • Iterator Design Pattern is a relatively simple design pattern, which we use almost in every project.
  • Few container requires an algorithm to access the member elements. Iterator Design Pattern decouples any such algorithm from the container.
  • The algorithm can be written separately to use by the Iterator and hence can be use by any container which supports that kind of Iterator object.
  • The Iterator Design Pattern provides flexible and reusable solution of traversing member objects of a container/collection. That make our collection object easier to implement, change, test and reuse.
  • Iterator object also facilitate removing of member object while traversing the collection. So, it's one of the solution of ConcurrentModificationException.

iterator design pattern

Here, the aggregate is nothing but the container/collection which offers Iterator to traverse itself.

Suppose, we have a List of names as below:

Java
xxxxxxxxxx
1
 
1
        List<String> names = new ArrayList<String>();
2
        names.add("Ajay");
3
        names.add("Vijay");
4
        names.add("Martin");
5
        names.add("Racheal");
6
        names.add("Kim");


Now to traverse the elements of it, we can use while loop like: 

Java
xxxxxxxxxx
1
 
1
        Iterator<String> namesIterator = names.iterator();
2
        while (namesIterator.hasNext()) {
3
            System.out.println("Hello! " + namesIterator.next());
4
        }


or by using for loop:

Java
xxxxxxxxxx
1
 
1
        for (Iterator namesIterator = names.iterator(); namesIterator.hasNext();) {
2
            System.out.println("Hello! " + namesIterator.next());
3
        }


Here, in both cases, we need to check availability of container member element by using hasNext() method before moving to next element by using next() method. Otherwise we will get NoSuchElementException.

There is also a super easy way of doing same by using for-each loop:

Java
 




xxxxxxxxxx
1


 
1
        for (String name : names) {
2
            System.out.println("Hello! " + name);
3
        }



For-each loops are tailor made and do not require checking collection boundaries while traversing.

Now, some examples to understand the implementation of the Iterator Pattern. I will use Java's Iterator interface in the example and will create only aggregate interface to get the instance of Iterator object.

Code for Container interface (deals with String containers since return type of the method is iterator of strings):

Java
xxxxxxxxxx
1
 
1
package org.trishinfotech.iterator.example1;
2
3
import java.util.Iterator;
4
5
public interface Container {
6
    public Iterator<String> getIterator();
7
}


Now, suppose we have a NamesRepository class which implements Container interface as below:

Java
xxxxxxxxxx
1
48
 
1
package org.trishinfotech.iterator.example1;
2
3
import java.util.Iterator;
4
5
public class NamesRepository implements Container {
6
7
    private String names[] = { "Ajay", "Vijay", "Martin", "Racheal", "Kim" };
8
9
    public NamesRepository() {
10
        super();
11
    }
12
13
    @Override
14
    public Iterator<String> getIterator() {
15
        return new CollectionofNamesIterate(this);
16
    }
17
18
    public String[] getNames() {
19
        return names;
20
    }
21
22
    public static class CollectionofNamesIterate implements Iterator<String> {
23
        private int currentElement = 0;
24
        private NamesRepository namesRepository;
25
26
        public CollectionofNamesIterate(NamesRepository namesRepository) {
27
            super();
28
            this.namesRepository = namesRepository;
29
        }
30
31
        @Override
32
        public boolean hasNext() {
33
            if (currentElement < namesRepository.names.length) {
34
                return true;
35
            }
36
            return false;
37
        }
38
39
        @Override
40
        public String next() {
41
            if (this.hasNext()) {
42
                return namesRepository.names[currentElement++];
43
            }
44
            return null;
45
        }
46
    }
47
}


Here, please note that I have created concrete implementation of Iterator interface as public static inner class of the repository class itself.

Now the Main program to execute and test the above code.

Java
xxxxxxxxxx
1
22
 
1
package org.trishinfotech.iterator.example1;
2
3
import java.util.Iterator;
4
5
public class Main {
6
7
    public static void main(String[] args) {
8
        NamesRepository repository = new NamesRepository();
9
        Iterator<String> repositoryIterator = repository.getIterator();
10
        while (repositoryIterator.hasNext()) {
11
            System.out.println("Hi! " + repositoryIterator.next());
12
        }
13
        
14
        // or in an easier way by using for each loop
15
        String[] names = repository.getNames();
16
        for (String name : names) {
17
            System.out.println("Hello! " + name);
18
        }
19
    }
20
21
}


Actually, it is availability of tailor made for-each loop which makes the processing easiest. And to achieve that for-each uses implicit iterator object with the help of Iterable interface.

Now, one more example of Books Collection to understand the Iterator pattern.

Book Library Application Using Iterator Design Pattern

I think by now we are clear on the Iterator Pattern and its uses. By the example below, I will try to eliminate the doubts if any while implementing the Iterator Pattern.

Code for Book class:

Java
xxxxxxxxxx
1
73
 
1
package org.trishinfotech.iterator;
2
3
public class Book {
4
5
    private String language;
6
    private String title;
7
    private String author;
8
    private long ISBN;
9
    private double price;
10
11
    public Book() {
12
        super();
13
    }
14
15
    public Book(String language, String title, String author, long ISBN, double price) {
16
        this();
17
        this.language = language;
18
        this.title = title;
19
        this.author = author;
20
        this.ISBN = ISBN;
21
        this.price = price;
22
    }
23
24
    public String getLanguage() {
25
        return language;
26
    }
27
28
    public void setLanguage(String language) {
29
        this.language = language;
30
    }
31
32
    public String getTitle() {
33
        return title;
34
    }
35
36
    public void setTitle(String title) {
37
        this.title = title;
38
    }
39
40
    public String getAuthor() {
41
        return author;
42
    }
43
44
    public void setAuthor(String author) {
45
        this.author = author;
46
    }
47
48
    public long getISBN() {
49
        return ISBN;
50
    }
51
52
    public void setISBN(long iSBN) {
53
        ISBN = iSBN;
54
    }
55
56
    public double getPrice() {
57
        return price;
58
    }
59
60
    public void setPrice(double price) {
61
        this.price = price;
62
    }
63
64
    @Override
65
    public String toString() {
66
        StringBuilder builder = new StringBuilder();
67
        builder.append("Book [language=").append(language).append(", title=").append(title).append(", author=")
68
                .append(author).append(", ISBN=").append(ISBN).append(", price=").append(price).append("]");
69
        return builder.toString();
70
    }
71
72
}


Code for BookCollection interface (aggregate interface):

Java
xxxxxxxxxx
1
 
1
package org.trishinfotech.iterator.example2;
2
3
import java.util.Iterator;
4
5
public interface BookCollection {
6
    public Iterator<Book> iterator();
7
}


The method name can be like getIterator() or simply iterator(). Now, we have two different versions of book-collections.

  • Variable number of books - BookLibrary.
  • Fixed and limited number of books - BookStore.

Code for BookLibrary class:

Java
xxxxxxxxxx
1
34
 
1
package org.trishinfotech.iterator.example2;
2
3
import java.util.ArrayList;
4
import java.util.Iterator;
5
import java.util.List;
6
7
public class BookLibrary implements BookCollection {
8
    protected List<Book> books;
9
10
    public BookLibrary() {
11
        super();
12
        books = new ArrayList<Book>();
13
    }
14
15
    public boolean addBook(String language, String title, String author, long ISBN, double price) {
16
        Book book = new Book(language, title, author, ISBN, price);
17
        return books.add(book);
18
    }
19
    
20
    public boolean addBook(Book book) {
21
        return books.add(book);
22
    }
23
    
24
    public List<Book> getBooks() {
25
        return books;
26
    }
27
28
    @Override
29
    public Iterator<Book> iterator() {
30
        return books.iterator();
31
    }
32
33
}


Here I am using Java provided Iterator object for the Collection.

Now the code for BookStore class:

Java
xxxxxxxxxx
1
48
 
1
package org.trishinfotech.iterator.example2;
2
3
import java.util.Iterator;
4
5
public class BookStore implements BookCollection {
6
    protected static int MAX_BOOKS = 1000;
7
    protected int totalBooks = 0;
8
    protected Book[] books;
9
10
    public BookStore() {
11
        super();
12
        books = new Book[MAX_BOOKS];
13
    }
14
15
    public boolean addBook(String language, String title, String author, long ISBN, double price) {
16
        Book book = new Book(language, title, author, ISBN, price);
17
        if (totalBooks < (MAX_BOOKS - 1)) {
18
            books[totalBooks++] = book;
19
            return true;
20
        } else {
21
            System.out.println("BookStore is full and can't accept any more books!");
22
            return false;
23
        }
24
    }
25
26
    public boolean addBook(Book book) {
27
        if (totalBooks < (MAX_BOOKS - 1)) {
28
            books[totalBooks++] = book;
29
            return true;
30
        } else {
31
            System.out.println("BookStore is full and can't accept any more books!");
32
            return false;
33
        }
34
    }
35
    
36
    public Book[] getBooks() {
37
        return books;
38
    }
39
40
    @Override
41
    public Iterator<Book> iterator() {
42
        return new BookIterator(books);
43
        // or simply use the below line to avoid writing explicit implementation of the iterator class.
44
        // return Arrays.stream(books).iterator();
45
    }
46
47
}


Here, I am using explicit implementation of concrete Iterator class to demonstrate how we can write it. We can also use implicit Iterator object as we did in the BookLibrary class.

Now the code for BookIterator class which offers iterating over array of books:

Java
xxxxxxxxxx
1
25
 
1
package org.trishinfotech.iterator.example2;
2
3
import java.util.Iterator;
4
5
public class BookIterator implements Iterator<Book> {
6
7
    protected Book[] books;
8
    protected int currentBook = 0;
9
    
10
    public BookIterator(Book[] books) {
11
        this.books = books;
12
    }
13
14
    @Override
15
    public boolean hasNext() {
16
        return (currentBook < books.length && books[currentBook] != null);
17
    }
18
19
    @Override
20
    public Book next() {
21
        return books[currentBook++];
22
    }
23
24
}


Now, it's ready to execute and test the output. So, lets write a Main program:

Java
xxxxxxxxxx
1
48
 
1
package org.trishinfotech.iterator.example2;
2
3
import java.util.Arrays;
4
import java.util.Iterator;
5
6
public class Main {
7
8
    public static void main(String[] args) {
9
        Book[] books = new Book[5];
10
        books[0] = new Book("English", "Head First Java, 2nd Edition", "Kathy Sierra", 10123758943l, 10.5d);
11
        books[1] = new Book("English", "Effective Java (3rd Edition)", "Bloch Joshua", 34422235432l, 8.65d);
12
        books[2] = new Book("English", "Mastering Java Machine Learning", "Dr Uday Kamath", 2123765476l, 21.45d);
13
        books[3] = new Book("English", "Cloud-Native Java", "Kenny Bastani ", 21332343434l, 28.99d);
14
        books[4] = new Book("English", "Java 9 Modularity", "Paul Bakker", 1645243587l, 36.68d);
15
        BookStore store = new BookStore();
16
        BookLibrary library = new BookLibrary();
17
        Arrays.stream(books).forEach(book -> {
18
            store.addBook(book);
19
            library.addBook(book);
20
        });
21
22
        System.out.println("Printing Book details of Book Store");
23
        System.out.println(
24
                "-------------------------------------------------------------------------------------------------");
25
        printBooks(store.iterator());
26
        System.out.println("Printing Book details of Book Library");
27
        System.out.println(
28
                "-------------------------------------------------------------------------------------------------");
29
        printBooks(library.iterator());
30
    }
31
32
    private static void printBooks(Iterator<Book> iterator) {
33
        // String language, String title, String author, long ISBN, double price
34
        System.out.printf("%10s | %35s | %15s | %15s | %10s\n", "Language", "Title", "Author", "ISBN", "Price");
35
        System.out.println(
36
                "-------------------------------------------------------------------------------------------------");
37
        while (iterator.hasNext()) {
38
            Book book = iterator.next();
39
            System.out.printf("%10s | %35s | %15s | %15s | %10.2f\n", book.getLanguage(), book.getTitle(),
40
                    book.getAuthor(), book.getISBN(), book.getPrice());
41
        }
42
        System.out.println(
43
                "-------------------------------------------------------------------------------------------------");
44
        System.out.println();
45
    }
46
47
}


And here's the output:

Java
xxxxxxxxxx
1
23
 
1
Printing Book details of Book Store
2
-------------------------------------------------------------------------------------------------
3
  Language |                               Title |          Author |            ISBN |      Price
4
-------------------------------------------------------------------------------------------------
5
   English |        Head First Java, 2nd Edition |    Kathy Sierra |     10123758943 |      10.50
6
   English |        Effective Java (3rd Edition) |    Bloch Joshua |     34422235432 |       8.65
7
   English |     Mastering Java Machine Learning |  Dr Uday Kamath |      2123765476 |      21.45
8
   English |                   Cloud-Native Java |  Kenny Bastani  |     21332343434 |      28.99
9
   English |                   Java 9 Modularity |     Paul Bakker |      1645243587 |      36.68
10
-------------------------------------------------------------------------------------------------
11
12
Printing Book details of Book Library
13
-------------------------------------------------------------------------------------------------
14
  Language |                               Title |          Author |            ISBN |      Price
15
-------------------------------------------------------------------------------------------------
16
   English |        Head First Java, 2nd Edition |    Kathy Sierra |     10123758943 |      10.50
17
   English |        Effective Java (3rd Edition) |    Bloch Joshua |     34422235432 |       8.65
18
   English |     Mastering Java Machine Learning |  Dr Uday Kamath |      2123765476 |      21.45
19
   English |                   Cloud-Native Java |  Kenny Bastani  |     21332343434 |      28.99
20
   English |                   Java 9 Modularity |     Paul Bakker |      1645243587 |      36.68
21
-------------------------------------------------------------------------------------------------


Now before I conclude this article, I like to discuss one more topic here.

Iterable Interface:

This is included in Java 5 and is part of java.lang package. An object that implements this interface allows it to be the target of the for-each loop. 

Let's see with the same Book Library example to understand how we can implement it.

All we need to do is: We have to make our BookStore and BookLibrary as sub-type of Iterable interface. Iterable interface will act as aggregator for us for Iterator Pattern.

And we have to implement only below method:

Java
xxxxxxxxxx
1
 
1
    /**
2
     * Returns an iterator over elements of type {@code T}.
3
     *
4
     * @return an Iterator.
5
     */
6
    Iterator<T> iterator();


Please notice that its with generics just like Iterator interface.

Book Library Application Using Iterator Design Pattern (Iterable Interface)

There is no change in the Book class. So, will use the same. Also, there is no need to have BookCollection interface since Iterable will serve that purpose.

Now code for BookLibrary class:

Java
xxxxxxxxxx
1
36
 
1
package org.trishinfotech.iterator.example3;
2
3
import java.util.ArrayList;
4
import java.util.Iterator;
5
import java.util.List;
6
7
import org.trishinfotech.iterator.Book;
8
9
public class BookLibrary implements Iterable<Book> {
10
    protected List<Book> books;
11
12
    public BookLibrary() {
13
        super();
14
        books = new ArrayList<Book>();
15
    }
16
17
    public boolean addBook(String language, String title, String author, long ISBN, double price) {
18
        Book book = new Book(language, title, author, ISBN, price);
19
        return books.add(book);
20
    }
21
    
22
    public boolean addBook(Book book) {
23
        return books.add(book);
24
    }
25
    
26
    public List<Book> getBooks() {
27
        return books;
28
    }
29
30
    @Override
31
    public Iterator<Book> iterator() {
32
        return books.iterator();
33
    }
34
35
}


Code for BookStore class:

Java
xxxxxxxxxx
1
51
 
1
package org.trishinfotech.iterator.example3;
2
3
import java.util.Iterator;
4
5
import org.trishinfotech.iterator.Book;
6
import org.trishinfotech.iterator.example2.BookIterator;
7
8
public class BookStore implements Iterable<Book> {
9
    protected static int MAX_BOOKS = 1000;
10
    protected int totalBooks = 0;
11
    protected Book[] books;
12
13
    public BookStore() {
14
        super();
15
        books = new Book[MAX_BOOKS];
16
    }
17
18
    public boolean addBook(String language, String title, String author, long ISBN, double price) {
19
        Book book = new Book(language, title, author, ISBN, price);
20
        if (totalBooks < (MAX_BOOKS - 1)) {
21
            books[totalBooks++] = book;
22
            return true;
23
        } else {
24
            System.out.println("BookStore is full and can't accept any more books!");
25
            return false;
26
        }
27
    }
28
29
    public boolean addBook(Book book) {
30
        if (totalBooks < (MAX_BOOKS - 1)) {
31
            books[totalBooks++] = book;
32
            return true;
33
        } else {
34
            System.out.println("BookStore is full and can't accept any more books!");
35
            return false;
36
        }
37
    }
38
    
39
    public Book[] getBooks() {
40
        return books;
41
    }
42
43
    @Override
44
    public Iterator<Book> iterator() {
45
        return new BookIterator(books);
46
        // or simply use the below line to avoid writing explicit implementation of the iterator class.
47
        // return Arrays.stream(books).iterator();
48
    }
49
50
}
51


Almost the same? Isn't it? And we are done! And you know what our previous code of Main will also work without any change. But, I like to show the simplicity of the code. 

Now its time to write Main program to execute and test the output:

Java
x
48
 
1
package org.trishinfotech.iterator.example3;
2
3
import java.util.Arrays;
4
5
import org.trishinfotech.iterator.Book;
6
7
public class Main {
8
9
    public static void main(String[] args) {
10
        Book[] books = new Book[5];
11
        books[0] = new Book("English", "Head First Java, 2nd Edition", "Kathy Sierra", 10123758943l, 10.5d);
12
        books[1] = new Book("English", "Effective Java (3rd Edition)", "Bloch Joshua", 34422235432l, 8.65d);
13
        books[2] = new Book("English", "Mastering Java Machine Learning", "Dr Uday Kamath", 2123765476l, 21.45d);
14
        books[3] = new Book("English", "Cloud-Native Java", "Kenny Bastani ", 21332343434l, 28.99d);
15
        books[4] = new Book("English", "Java 9 Modularity", "Paul Bakker", 1645243587l, 36.68d);
16
        BookStore store = new BookStore();
17
        BookLibrary library = new BookLibrary();
18
        Arrays.stream(books).forEach(book -> {
19
            store.addBook(book);
20
            library.addBook(book);
21
        });
22
23
        System.out.println("Printing Book details of Book Store");
24
        System.out.println(
25
                "-------------------------------------------------------------------------------------------------");
26
        printBooks(store);
27
        System.out.println("Printing Book details of Book Library");
28
        System.out.println(
29
                "-------------------------------------------------------------------------------------------------");
30
        printBooks(library);
31
    }
32
33
    private static void printBooks(Iterable<Book> books) {
34
        // String language, String title, String author, long ISBN, double price
35
        System.out.printf("%10s | %35s | %15s | %15s | %10s\n", "Language", "Title", "Author", "ISBN", "Price");
36
        System.out.println(
37
                "-------------------------------------------------------------------------------------------------");
38
        for (Book book : books) {
39
            System.out.printf("%10s | %35s | %15s | %15s | %10.2f\n", book.getLanguage(), book.getTitle(),
40
                    book.getAuthor(), book.getISBN(), book.getPrice());
41
        }
42
        System.out.println(
43
                "-------------------------------------------------------------------------------------------------");
44
        System.out.println();
45
    }
46
47
}


Well you have it! I hope you are clear with examples on Iterator Design Pattern.

Source Code can be found here: Iterator Design Pattern Source Code

Liked this article? Don't forget to press that like button. Happy coding! 

Need more articles, please visit my profile: Brijesh Saxena

Java (programming language) Design Interface (computing) Object (computer science) Book

Opinions expressed by DZone contributors are their own.

Related

  • Composite Design Pattern in Java
  • Object Relational Behavioral Design Patterns in Java
  • Distribution Design Patterns in Java - Data Transfer Object (DTO) And Remote Facade Design Patterns
  • Context Object Design Pattern in Java: Introduction and Key Points

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!