1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.collections4.iterators; 18 19 import java.util.NoSuchElementException; 20 21 import org.apache.commons.collections4.ResettableListIterator; 22 23 /** 24 * Implements a {@link java.util.ListIterator} over an array of objects. 25 * <p> 26 * This iterator does not support {@link #add} or {@link #remove}, as the object array 27 * cannot be structurally modified. The {@link #set} method is supported however. 28 * <p> 29 * The iterator implements a {@link #reset} method, allowing the reset of the iterator 30 * back to the start if required. 31 * 32 * @param <E> the type of elements returned by this iterator. 33 * @see org.apache.commons.collections4.iterators.ObjectArrayIterator 34 * @see java.util.Iterator 35 * @see java.util.ListIterator 36 * 37 * @since 3.0 38 */ 39 public class ObjectArrayListIterator<E> extends ObjectArrayIterator<E> 40 implements ResettableListIterator<E> { 41 42 /** 43 * Holds the index of the last item returned by a call to {@code next()} 44 * or {@code previous()}. This is set to {@code -1} if neither method 45 * has yet been invoked. {@code lastItemIndex} is used to implement the 46 * {@link #set} method. 47 */ 48 private int lastItemIndex = -1; 49 50 /** 51 * Constructs an ObjectArrayListIterator that will iterate over the values in the 52 * specified array. 53 * 54 * @param array the array to iterate over 55 * @throws NullPointerException if {@code array} is {@code null} 56 */ 57 public ObjectArrayListIterator(final E... array) { 58 super(array); 59 } 60 61 /** 62 * Constructs an ObjectArrayListIterator that will iterate over the values in the 63 * specified array from a specific start index. 64 * 65 * @param array the array to iterate over 66 * @param start the index to start iterating at 67 * @throws NullPointerException if {@code array} is {@code null} 68 * @throws IndexOutOfBoundsException if the start index is out of bounds 69 */ 70 public ObjectArrayListIterator(final E[] array, final int start) { 71 super(array, start); 72 } 73 74 /** 75 * Constructs an ObjectArrayListIterator that will iterate over a range of values 76 * in the specified array. 77 * 78 * @param array the array to iterate over 79 * @param start the index to start iterating at 80 * @param end the index (exclusive) to finish iterating at 81 * @throws IndexOutOfBoundsException if the start or end index is out of bounds 82 * @throws IllegalArgumentException if end index is before the start 83 * @throws NullPointerException if {@code array} is {@code null} 84 */ 85 public ObjectArrayListIterator(final E[] array, final int start, final int end) { 86 super(array, start, end); 87 } 88 89 /** 90 * This iterator does not support modification of its backing array's size, and so will 91 * always throw an {@link UnsupportedOperationException} when this method is invoked. 92 * 93 * @param obj the object to add 94 * @throws UnsupportedOperationException always thrown. 95 */ 96 @Override 97 public void add(final E obj) { 98 throw new UnsupportedOperationException("add() method is not supported"); 99 } 100 101 /** 102 * Returns true if there are previous elements to return from the array. 103 * 104 * @return true if there is a previous element to return 105 */ 106 @Override 107 public boolean hasPrevious() { 108 return this.index > getStartIndex(); 109 } 110 111 /** 112 * Gets the next element from the array. 113 * 114 * @return the next element 115 * @throws NoSuchElementException if there is no next element 116 */ 117 @Override 118 public E next() { 119 if (!hasNext()) { 120 throw new NoSuchElementException(); 121 } 122 this.lastItemIndex = this.index; 123 return this.array[this.index++]; 124 } 125 126 /** 127 * Gets the next index to be retrieved. 128 * 129 * @return the index of the item to be retrieved next 130 */ 131 @Override 132 public int nextIndex() { 133 return this.index - getStartIndex(); 134 } 135 136 /** 137 * Gets the previous element from the array. 138 * 139 * @return the previous element 140 * @throws NoSuchElementException if there is no previous element 141 */ 142 @Override 143 public E previous() { 144 if (!hasPrevious()) { 145 throw new NoSuchElementException(); 146 } 147 this.lastItemIndex = --this.index; 148 return this.array[this.index]; 149 } 150 151 /** 152 * Gets the index of the item to be retrieved if {@link #previous()} is called. 153 * 154 * @return the index of the item to be retrieved next 155 */ 156 @Override 157 public int previousIndex() { 158 return this.index - getStartIndex() - 1; 159 } 160 161 /** 162 * Resets the iterator back to the start index. 163 */ 164 @Override 165 public void reset() { 166 super.reset(); 167 this.lastItemIndex = -1; 168 } 169 170 /** 171 * Sets the element under the cursor. 172 * <p> 173 * This method sets the element that was returned by the last call 174 * to {@link #next()} of {@link #previous()}. 175 * 176 * <b>Note:</b> {@link java.util.ListIterator} implementations that support {@code add()} 177 * and {@code remove()} only allow {@code set()} to be called once per call 178 * to {@code next()} or {@code previous} (see the {@link java.util.ListIterator} 179 * Javadoc for more details). Since this implementation does not support 180 * {@code add()} or {@code remove()}, {@code set()} may be 181 * called as often as desired. 182 * 183 * @param obj the object to set into the array 184 * @throws IllegalStateException if next() has not yet been called. 185 * @throws ClassCastException if the object type is unsuitable for the array 186 */ 187 @Override 188 public void set(final E obj) { 189 if (this.lastItemIndex == -1) { 190 throw new IllegalStateException("must call next() or previous() before a call to set()"); 191 } 192 193 this.array[this.lastItemIndex] = obj; 194 } 195 196 }