2

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?

2
  • 2
    I would do it without a reverseIterator method. It is pretty rare for your own code to need to deal with an Iterator directly, and if you really want one then you can call reverseIterable().iterator(). Also note that you can neaten up the reverseIterator method by just returning ReverseEntryIterator::new in Java 8+. Commented Oct 18, 2021 at 21:35
  • List provides both iterator() and listIterator(), so this looks like a fairly reasonable approach. Commented Oct 18, 2021 at 21:51

2 Answers 2

1

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).

Sign up to request clarification or add additional context in comments.

Comments

0

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();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.