@ Override public Iterator < T > iterator ( ) { /* * We make a copy of the allResults list to iterate over in order to * avoid ConcurrentModificationExceptions caused by other methods * loading more results into the list while someone iterates over it. * This is a more severe problem than it might seem, because even * innocuous-seeming operations such as contains() can modify the * underlying result set. */ final List < T > allResultsCopy = new ArrayList < T > ( ) ; allResultsCopy . addAll ( allResults ) ; final Iterator < T > iter = allResultsCopy . iterator ( ) ; return new Iterator < T > ( ) { Iterator < T > iterator = iter ; int pos = 0 ; @ Override public boolean hasNext ( ) { return iterator . hasNext ( ) || nextResultsAvailable ( ) ; } @ Override public T next ( ) { if ( ! iterator . hasNext ( ) ) { /* * Our private copy of the result list may be out of date * with the full one. If it is, we just need to update our * private copy to get more results. If it's not, we need to * fetch more results from the service. */ if ( allResults . size ( ) == allResultsCopy . size ( ) ) { if ( ! nextResultsAvailable ( ) ) { throw new NoSuchElementException ( ) ; } moveNextResults ( ) ; } if ( allResults . size ( ) > allResultsCopy . size ( ) ) allResultsCopy . addAll ( allResults . subList ( allResultsCopy . size ( ) , allResults . size ( ) ) ) ; iterator = allResultsCopy . listIterator ( pos ) ; } pos ++ ; return iterator . next ( ) ; } @ Override public void remove ( ) { throw new UnsupportedOperationException ( UNMODIFIABLE_MESSAGE ) ; } } ; }
Returns an iterator over this list that lazily initializes results as necessary .