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