public boolean hasNext() {
if (nextShort != null) // found it already
return true;
while (strings.hasNext()) {
nextShort = strings.next();
if (nextShort.length() <= maxLen)
return true;
}
nextShort = null; // didn't find one
return false;
}
public String next() {
if (nextShort == null && !hasNext())
throw new NoSuchElementException();
String n = nextShort; // remember nextShort
nextShort = null; // consume nextShort
return n; // return nextShort
}
public void remove() {
throw new UnsupportedOperationException();
}
}
The class ShortStrings is a type of iterator that will read String objects from another iterator, returning
only those that are no longer than a specified length. The constructor takes the iterator that will provide the
strings and the maximum length, storing those in the object's fields. The field nextShort will hold the next
short string, or null when there isn't one. If nextShort is null, the hasNext method searches for the
next short string, remembering it in nextShort. If hasNext reaches the end of its source iteration without
finding a short string it returns false.
The method next checks to see if there is a next short string, either returning it if there is one or throwing
NoSuchElementException if there are none to return. Notice that hasNext does all the real work of
finding the short strings, and next just returns the results, setting nextShort to null to indicate that the
next short string, if any, is as yet undiscovered.
Finally, remove is not supported by this iterator implementation, so remove throws
UnsupportedOperationException.
A few things to notice. First, hasNext is carefully written so that it will work if invoked multiple times
before a next. This is requiredthe calling code may invoke hasNext as many times as it wants between
invocations of next. Second, next is carefully written so that it works even if programmer using it has
never invoked hasNext. Although generally a poor practice, you could never invoke hasNext and simply
loop invoking next until an exception is generated.
Third, remove is not allowed because it cannot work correctly. Imagine, for example, if remove invoked
remove on the underlying iterator. The following legal (although odd) code can cause incorrect behavior:
it.next();
it.hasNext();
it.remove();
Imagine that this were to happen when there was one more short string left in the iteration followed by some
long ones. The invocation of next would return the last short string. Then hasNext would iterate through