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 * @see org.apache.commons.collections4.iterators.ObjectArrayIterator 33 * @see java.util.Iterator 34 * @see java.util.ListIterator 35 * 36 * @since 3.0 37 */ 38 public class ObjectArrayListIterator<E> extends ObjectArrayIterator<E> 39 implements ResettableListIterator<E> { 40 41 /** 42 * Holds the index of the last item returned by a call to <code>next()</code> 43 * or <code>previous()</code>. This is set to <code>-1</code> if neither method 44 * has yet been invoked. <code>lastItemIndex</code> is used to to implement the 45 * {@link #set} method. 46 */ 47 private int lastItemIndex = -1; 48 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</code> is <code>null</code> 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</code> is <code>null</code> 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 * Construct 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</code> is <code>null</code> 84 */ 85 public ObjectArrayListIterator(final E[] array, final int start, final int end) { 86 super(array, start, end); 87 } 88 89 // ListIterator interface 90 //------------------------------------------------------------------------- 91 92 /** 93 * Returns true if there are previous elements to return from the array. 94 * 95 * @return true if there is a previous element to return 96 */ 97 @Override 98 public boolean hasPrevious() { 99 return this.index > getStartIndex(); 100 } 101 102 /** 103 * Gets the previous element from the array. 104 * 105 * @return the previous element 106 * @throws NoSuchElementException if there is no previous element 107 */ 108 @Override 109 public E previous() { 110 if (hasPrevious() == false) { 111 throw new NoSuchElementException(); 112 } 113 this.lastItemIndex = --this.index; 114 return this.array[this.index]; 115 } 116 117 /** 118 * Gets the next element from the array. 119 * 120 * @return the next element 121 * @throws NoSuchElementException if there is no next element 122 */ 123 @Override 124 public E next() { 125 if (hasNext() == false) { 126 throw new NoSuchElementException(); 127 } 128 this.lastItemIndex = this.index; 129 return this.array[this.index++]; 130 } 131 132 /** 133 * Gets the next index to be retrieved. 134 * 135 * @return the index of the item to be retrieved next 136 */ 137 @Override 138 public int nextIndex() { 139 return this.index - getStartIndex(); 140 } 141 142 /** 143 * Gets the index of the item to be retrieved if {@link #previous()} is called. 144 * 145 * @return the index of the item to be retrieved next 146 */ 147 @Override 148 public int previousIndex() { 149 return this.index - getStartIndex() - 1; 150 } 151 152 /** 153 * This iterator does not support modification of its backing array's size, and so will 154 * always throw an {@link UnsupportedOperationException} when this method is invoked. 155 * 156 * @param obj the object to add 157 * @throws UnsupportedOperationException always thrown. 158 */ 159 @Override 160 public void add(final E obj) { 161 throw new UnsupportedOperationException("add() method is not supported"); 162 } 163 164 /** 165 * Sets the element under the cursor. 166 * <p> 167 * This method sets the element that was returned by the last call 168 * to {@link #next()} of {@link #previous()}. 169 * 170 * <b>Note:</b> {@link java.util.ListIterator} implementations that support <code>add()</code> 171 * and <code>remove()</code> only allow <code>set()</code> to be called once per call 172 * to <code>next()</code> or <code>previous</code> (see the {@link java.util.ListIterator} 173 * javadoc for more details). Since this implementation does not support 174 * <code>add()</code> or <code>remove()</code>, <code>set()</code> may be 175 * called as often as desired. 176 * 177 * @param obj the object to set into the array 178 * @throws IllegalStateException if next() has not yet been called. 179 * @throws ClassCastException if the object type is unsuitable for the array 180 */ 181 @Override 182 public void set(final E obj) { 183 if (this.lastItemIndex == -1) { 184 throw new IllegalStateException("must call next() or previous() before a call to set()"); 185 } 186 187 this.array[this.lastItemIndex] = obj; 188 } 189 190 /** 191 * Resets the iterator back to the start index. 192 */ 193 @Override 194 public void reset() { 195 super.reset(); 196 this.lastItemIndex = -1; 197 } 198 199 }