private boolean moveToNext() { try { Notification<? extends T> nextNotification = observer.takeNext(); if (nextNotification.isOnNext()) { isNextConsumed = false; next = nextNotification.getValue(); return true; } // If an observable is completed or fails, // hasNext() always return false. hasNext = false; if (nextNotification.isOnCompleted()) { return false; } if (nextNotification.isOnError()) { error = nextNotification.getThrowable(); throw Exceptions.propagate(error); } throw new IllegalStateException("Should not reach here"); } catch (InterruptedException e) { Thread.currentThread().interrupt(); error = e; throw Exceptions.propagate(error); } }
@Override public T next() { if (error != null) { // If any error has already been thrown, throw it again. throw Exceptions.propagate(error); } if (hasNext()) { isNextConsumed = true; return next; } else { throw new NoSuchElementException("No more elements"); } }
@Override public boolean hasNext() { if (error != null) { // If any error has already been thrown, throw it again. throw Exceptions.propagate(error); } // Since an iterator should not be used in different thread, // so we do not need any synchronization. if (hasNext == false) { // the iterator has reached the end. return false; } if (isNextConsumed == false) { // next has not been used yet. return true; } return moveToNext(); }