1 /* 2 * Copyright (C) 2009 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.collect; 18 19 import static com.google.common.base.Preconditions.checkPositionIndex; 20 21 import com.google.common.annotations.GwtCompatible; 22 23 import java.util.ListIterator; 24 import java.util.NoSuchElementException; 25 26 /** 27 * This class provides a skeletal implementation of the {@link ListIterator} 28 * interface across a fixed number of elements that may be retrieved by 29 * position. It does not support {@link #remove}, {@link #set}, or {@link #add}. 30 * 31 * @author Jared Levy 32 */ 33 @GwtCompatible 34 abstract class AbstractIndexedListIterator<E> 35 extends UnmodifiableListIterator<E> { 36 private final int size; 37 private int position; 38 39 /** 40 * Returns the element with the specified index. This method is called by 41 * {@link #next()}. 42 */ 43 protected abstract E get(int index); 44 45 /** 46 * Constructs an iterator across a sequence of the given size whose initial 47 * position is 0. That is, the first call to {@link #next()} will return the 48 * first element (or throw {@link NoSuchElementException} if {@code size} is 49 * zero). 50 * 51 * @throws IllegalArgumentException if {@code size} is negative 52 */ 53 protected AbstractIndexedListIterator(int size) { 54 this(size, 0); 55 } 56 57 /** 58 * Constructs an iterator across a sequence of the given size with the given 59 * initial position. That is, the first call to {@link #nextIndex()} will 60 * return {@code position}, and the first call to {@link #next()} will return 61 * the element at that index, if available. Calls to {@link #previous()} can 62 * retrieve the preceding {@code position} elements. 63 * 64 * @throws IndexOutOfBoundsException if {@code position} is negative or is 65 * greater than {@code size} 66 * @throws IllegalArgumentException if {@code size} is negative 67 */ 68 protected AbstractIndexedListIterator(int size, int position) { 69 checkPositionIndex(position, size); 70 this.size = size; 71 this.position = position; 72 } 73 74 @Override 75 public final boolean hasNext() { 76 return position < size; 77 } 78 79 @Override 80 public final E next() { 81 if (!hasNext()) { 82 throw new NoSuchElementException(); 83 } 84 return get(position++); 85 } 86 87 @Override 88 public final int nextIndex() { 89 return position; 90 } 91 92 @Override 93 public final boolean hasPrevious() { 94 return position > 0; 95 } 96 97 @Override 98 public final E previous() { 99 if (!hasPrevious()) { 100 throw new NoSuchElementException(); 101 } 102 return get(--position); 103 } 104 105 @Override 106 public final int previousIndex() { 107 return position - 1; 108 } 109 } 110