I don't agree with Marshall's example. I've tried to do exactly what
you have proposed below, and I believe there is just no way to employ
Java 5's new for loops on an FSIndex or FSIterator without building a
new wrapper class. In particular:
1) The new Java 5 syntax applies only to arrays and to classes that
implement the Iterable interface (which defines the Iterator<T>
iterator() method).
2) The Java Iterator class does not implement Iterable; it does not have
an iterator() method (if they had put this into Java 5, it would have
broken all of the user defined iterators that already existed).
3) Java 5 Collection implements Iterable, but an FSIndex is not a
Collection and it does not implement Iterable (even though it does have
an iterator() method, as Iterable does).
However, if you are doing this often, it may be worth making such a
wrapper class, e.g.:
public class FSIndexIterable<T extends FeatureStructure> implements
Iterable<T> {
FSIndex index;
public FSIndexIterable(FSIndex index) {
this.index = index;
}
public Iterator<T> iterator() {
return (Iterator<T>)index.iterator();
}
}
And then making the following changes to Marshall's example:
FSIndex anIndex = aCas.getAnnotationIndex(Email.type);
* FSIndexIterable<AnnotationFS> anIndexIterable = new
FSIndexIterable<AnnotationFS>(anIndex);*
Iterator<AnnotationFS> anIter =
(Iterator<AnnotationFS>)anIndex.iterator();
assertTrue(anIter.hasNext());
int i = 0;
for (AnnotationFS annot : *anIndexIterable*) {
assertEquals("it.celi.type.Email",
annot.getType().getName()); assertEquals(mail[i],
annot.getCoveredText());
i++;
}
As with Marshall's example, this is untested so corrections are welcome.
Of course, it would be convenient if FSIndex just implemented Iterable
so we didn't need a wrapper here. However, I do not know if there is
any way to do that without breaking compatibility with earlier versions
of Java.
- Bill Murdock (IBM internal UIMA user but not a UIMA framework
developer or official spokesperson)
In particular, Java 5's Iterator interface does
Marshall Schor wrote:
Nice example, Roberto :-)
If you're using Java 5 or later, since the FSIterator is a
sub-interface of the Java Iterator, you can use the Java 5 style of
iterating. Here's an example (not tested - so there may be silly
mistakes - if so, please correct :-) :
// get annotation iterator for this CAS (Email is my type
FSIndex anIndex = aCas.getAnnotationIndex(Email.type);
Iterator<AnnotationFS> anIter =
(Iterator<AnnotationFS>)anIndex.iterator();
assertTrue(anIter.hasNext());
int i = 0;
for (AnnotationFS annot : anIter) {
assertEquals("it.celi.type.Email",
annot.getType().getName());
assertEquals(mail[i], annot.getCoveredText());
i++;
}
-Marshall