001 /* 002 * Copyright (C) 2010 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package com.google.common.collect; 018 019 import com.google.common.annotations.Beta; 020 import com.google.common.annotations.GwtCompatible; 021 022 import java.util.NoSuchElementException; 023 024 import javax.annotation.Nullable; 025 026 /** 027 * This class provides a skeletal implementation of the {@code Iterator} 028 * interface for sequences whose next element can always be derived from the 029 * previous element. Null elements are not supported, nor is the 030 * {@link #remove()} method. 031 * 032 * <p>Example: <pre> {@code 033 * 034 * Iterator<Integer> powersOfTwo = new AbstractLinkedIterator<Integer>(1) { 035 * protected Integer computeNext(Integer previous) { 036 * return (previous == 1 << 30) ? null : previous * 2; 037 * } 038 * };}</pre> 039 * 040 * @author Chris Povirk 041 * @since 8.0 042 */ 043 @Beta 044 @GwtCompatible 045 public abstract class AbstractLinkedIterator<T> 046 extends UnmodifiableIterator<T> { 047 private T nextOrNull; 048 049 /** 050 * Creates a new iterator with the given first element, or, if {@code 051 * firstOrNull} is null, creates a new empty iterator. 052 */ 053 protected AbstractLinkedIterator(@Nullable T firstOrNull) { 054 this.nextOrNull = firstOrNull; 055 } 056 057 /** 058 * Returns the element that follows {@code previous}, or returns {@code null} 059 * if no elements remain. This method is invoked during each call to 060 * {@link #next()} in order to compute the result of a <i>future</i> call to 061 * {@code next()}. 062 */ 063 protected abstract T computeNext(T previous); 064 065 @Override 066 public final boolean hasNext() { 067 return nextOrNull != null; 068 } 069 070 @Override 071 public final T next() { 072 if (!hasNext()) { 073 throw new NoSuchElementException(); 074 } 075 try { 076 return nextOrNull; 077 } finally { 078 nextOrNull = computeNext(nextOrNull); 079 } 080 } 081 }