Skip to content

Instantly share code, notes, and snippets.

@jimwhite
Last active August 29, 2015 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jimwhite/b2e73ae072d38da2452b to your computer and use it in GitHub Desktop.
Save jimwhite/b2e73ae072d38da2452b to your computer and use it in GitHub Desktop.
PoC for iterating over multiple collections in Groovy
// Example of an iterator that works over a sequence of multiple collections.
def a = [1, 2]
def b = [3, 4]
def c = new CollectionSequence(a, b)
// The elements of the collections look like one concatenated list.
println (c as List)
// Mutating the elements of one of the collections changes what we get.
// This is a "live" view of the member collections.
a.clear()
a.addAll([5, 6])
println (c as List)
// Make sure we work even for folks who like exceptions rather than using hasNext.
try {
def i = c.iterator()
while (true) {
print i.next()
print " "
}
} catch (NoSuchElementException e) {
println "EOL!"
}
// Groovy ignores the generic type but I include it to help illustrate the code.
class CollectionSequence<T> implements Iterable<T> {
List<Collection<T>> lists
CollectionSequence(Collection<T>... lists) {
this.lists = lists as List
}
Iterator<T> iterator() {
new Iterator<T>() {
Iterator<Collection<T>> listsIterator = lists.iterator()
Iterator<T> head = listsIterator.next().iterator()
boolean hasNext() {
boolean f = head.hasNext()
if (!f && listsIterator.hasNext()) {
head = listsIterator.next().iterator()
f = head.hasNext()
}
f
}
T next() {
try {
head.next()
} catch (NoSuchElementException ex) {
if (!listsIterator.hasNext()) throw ex
head = listsIterator.next().iterator()
next()
}
}
void remove() { head.remove() }
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment