Home > Enterprise >  Java pattern for reverse iterator and iterable methods?
Java pattern for reverse iterator and iterable methods?

Time:10-19

If a class implements the Iterable interface, e.g.

class Query implements Iterable<Query.Entry> {

    class Entry {
        // ...
    }

    @Override
    public Iterator<Entry> iterator() {
        return new EntryIterator();
    }   
}

then using an enhanced for is possible,

Query q;
// ...
for( Query.Entry e : q ) {
    // ...
}

but now needs to support other ways to perform iteration, e.g.

class Query implements Iterable<Query.Entry> {

    class Entry {
        // ...
    }

    @Override
    public Iterator<Entry> iterator() {
        return new EntryIterator();
    }   

    // new methods for reverse iteration
    public Iterator<Entry> reverseIterator() {
        return new ReverseEntryIterator();
    }

    public Iterable<Entry> reverseIterable() {
        return new Iterable<Entry>() {
            @Override
            public Iterator<Entry> iterator() {
                return new ReverseEntryIterator();
            }
        };
    }
}

would there be a "standard" way of doing this? The above code adds reverseIterable and reverseIterator, but looks somewhat messy. Maybe its better style to do without a reverseIterable method?

CodePudding user response:

You can omit the definition of the ReverseEntryIterator class by using an anonymous inner class.

Since Iterable is a functional interface that only defines the iterator() method, reverseIterable() can be defined as a method that returns a lambda expression.

// new methods for reverse iteration
public Iterator<Entry> reverseIterator() {
    return new Iterator<Entry>() {

        @Override
        public boolean hasNext() {
            // ...
        }

        @Override
        public Entry next() {
            // ...
        }
    };
}

public Iterable<Entry> reverseIterable() {
    return () -> reverseIterator();
}

CodePudding user response:

Another approach would be to just use iterator() itself on a reverse view of the forward order.

That would allow you to write code like this:

for( Query.Entry e : q.reverse() ) {
   // ...
} 

If you already have a List representation, implementing the reverse() function can be easy, either with the O(n) java.util.Collections.reverse(List) or Guava's O(1) com.google.common.collect.Lists.reverse(List).

  •  Tags:  
  • java
  • Related