NOTE

Iterator Pattern

Iterator-pattern notes showing Java and Go implementations for traversing aggregate objects.

Software Architecture & Engineering1 min readhistorical

This is a historical learning note and may contain outdated or incomplete understanding.

1. Definition

Provides a way to traverse aggregate objects; the JDK already provides this abstraction.

2. Java

2.1. Client

public class Client
{
    public static void main(String[] args)
    {
        List<String> list = Arrays.asList(new String[]{"a","b","c"});


        MyIterrator<String> iterrator = new StringIterator(list);
        while (iterrator.hasNext())
        {
            String current = iterrator.getCurrent();
            System.out.println(current);
            System.out.println(iterrator.isLast());
            iterrator.next();
        }
    }
}

2.2. Iterator

public interface MyIterrator <T>
{
    void first();
    void next();
    boolean hasNext();
    boolean isFirst();
    boolean isLast();
    T getCurrent();
}
public class StringIterator<T> implements MyIterrator<T>
{
    private int cursor = 0;
    private List<T> list = new ArrayList<>();

    public StringIterator(List<T> list)
    {
        this.list = list;
    }

    @Override
    public void first()
    {
        this.cursor = 0;
    }

    @Override
    public void next()
    {
        if (cursor == list.size())
            throw new RuntimeException("Index out of bounds");
        cursor++;

    }

    @Override
    public boolean hasNext()
    {
        return cursor < list.size();
    }

    @Override
    public boolean isFirst()
    {
        return cursor == 0;
    }

    @Override
    public boolean isLast()
    {
        return cursor == list.size()-1;
    }

    @Override
    public T getCurrent()
    {
        return this.list.get(cursor);
    }
}

3. Golang

3.1. Iterator


/* Interface for aggregate objects */
type Aggregate interface {
	// Return an iterator
	Iterator() Iterator
}

/* Iterator for aggregate objects */
type Iterator interface {
	First()
	IsDone() bool
	Next() interface{}
}

/* Aggregate object: Numbers */
type Numbers struct {
	start, end int
}

func (n *Numbers) Iterator() Iterator {
	return &NumbersIterator{
		numbers: n,
		next:    n.start,
	}
}

func NewNumbers(start int, end int) *Numbers {
	return &Numbers{start: start, end: end}
}

/* Iterator for Numbers */

type NumbersIterator struct {
	numbers *Numbers
	next    int
}

func (n *NumbersIterator) First() {
	n.next = n.numbers.start
}

func (n *NumbersIterator) IsDone() bool {
	return n.next > n.numbers.end
}

func (n *NumbersIterator) Next() interface{} {
	if !n.IsDone() {
		next := n.next
		n.next++
		return next
	}
	return nil
}

func IteratorPrint(i Iterator) {
	for i.First(); !i.IsDone(); {
		c := i.Next()
		fmt.Printf("%#v\n", c)
	}
}

3.2. Client

func main() {
	numbers := iterator.NewNumbers(1, 10)
	iterator.IteratorPrint(numbers.Iterator())
}

Discussion

Sign in with GitHub to comment. Discussions are stored as GitHub Issues.View on GitHub