View Javadoc
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    *      https://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.ListIterator;
20  import java.util.NoSuchElementException;
21  
22  import org.apache.commons.collections4.ResettableListIterator;
23  
24  /**
25   * Implements a {@link ListIterator} over an array of objects.
26   * <p>
27   * This iterator does not support {@link #add} or {@link #remove}, as the object array
28   * cannot be structurally modified. The {@link #set} method is supported however.
29   * </p>
30   * <p>
31   * The iterator implements a {@link #reset} method, allowing the reset of the iterator
32   * back to the start if required.
33   * </p>
34   *
35   * @param <E> The type of elements returned by this iterator.
36   * @see org.apache.commons.collections4.iterators.ObjectArrayIterator
37   * @see java.util.Iterator
38   * @see java.util.ListIterator
39   * @since 3.0
40   */
41  public class ObjectArrayListIterator<E> extends ObjectArrayIterator<E>
42          implements ResettableListIterator<E> {
43  
44      /**
45       * Holds the index of the last item returned by a call to {@code next()}
46       * or {@code previous()}. This is set to {@code -1} if neither method
47       * has yet been invoked. {@code lastItemIndex} is used to implement the
48       * {@link #set} method.
49       */
50      private int lastItemIndex = -1;
51  
52      /**
53       * Constructs an ObjectArrayListIterator that will iterate over the values in the
54       * specified array.
55       *
56       * @param array The array to iterate over
57       * @throws NullPointerException if {@code array} is {@code null}
58       */
59      public ObjectArrayListIterator(final E... array) {
60          super(array);
61      }
62  
63      /**
64       * Constructs an ObjectArrayListIterator that will iterate over the values in the
65       * specified array from a specific start index.
66       *
67       * @param array  The array to iterate over
68       * @param start  The index to start iterating at
69       * @throws NullPointerException if {@code array} is {@code null}
70       * @throws IndexOutOfBoundsException if the start index is out of bounds
71       */
72      public ObjectArrayListIterator(final E[] array, final int start) {
73          super(array, start);
74      }
75  
76      /**
77       * Constructs an ObjectArrayListIterator that will iterate over a range of values
78       * in the specified array.
79       *
80       * @param array  The array to iterate over
81       * @param start  The index to start iterating at
82       * @param end  The index (exclusive) to finish iterating at
83       * @throws IndexOutOfBoundsException if the start or end index is out of bounds
84       * @throws IllegalArgumentException if end index is before the start
85       * @throws NullPointerException if {@code array} is {@code null}
86       */
87      public ObjectArrayListIterator(final E[] array, final int start, final int end) {
88          super(array, start, end);
89      }
90  
91      /**
92       * Always throws {@link UnsupportedOperationException}.
93       *
94       * @param obj Ignored.
95       * @throws UnsupportedOperationException Always thrown.
96       */
97      @Override
98      public void add(final E obj) {
99          throw new UnsupportedOperationException("add() method is not supported");
100     }
101 
102     /**
103      * Returns true if there are previous elements to return from the array.
104      *
105      * @return true if there is a previous element to return
106      */
107     @Override
108     public boolean hasPrevious() {
109         return index > getStartIndex();
110     }
111 
112     /**
113      * Gets the next element from the array.
114      *
115      * @return The next element
116      * @throws NoSuchElementException if there is no next element
117      */
118     @Override
119     public E next() {
120         if (!hasNext()) {
121             throw new NoSuchElementException();
122         }
123         lastItemIndex = index;
124         return array[index++];
125     }
126 
127     /**
128      * Gets the next index to be retrieved.
129      *
130      * @return The index of the item to be retrieved next
131      */
132     @Override
133     public int nextIndex() {
134         return index - getStartIndex();
135     }
136 
137     /**
138      * Gets the previous element from the array.
139      *
140      * @return The previous element
141      * @throws NoSuchElementException if there is no previous element
142      */
143     @Override
144     public E previous() {
145         if (!hasPrevious()) {
146             throw new NoSuchElementException();
147         }
148         lastItemIndex = --index;
149         return array[index];
150     }
151 
152     /**
153      * Gets the index of the item to be retrieved if {@link #previous()} is called.
154      *
155      * @return The index of the item to be retrieved next
156      */
157     @Override
158     public int previousIndex() {
159         return index - getStartIndex() - 1;
160     }
161 
162     /**
163      * Resets the iterator back to the start index.
164      */
165     @Override
166     public void reset() {
167         super.reset();
168         lastItemIndex = -1;
169     }
170 
171     /**
172      * Sets the element under the cursor.
173      * <p>
174      * This method sets the element that was returned by the last call
175      * to {@link #next()} of {@link #previous()}.
176      * </p>
177      * <p>
178      * <strong>Note:</strong> {@link ListIterator} implementations that support {@code add()}
179      * and {@code remove()} only allow {@code set()} to be called once per call
180      * to {@code next()} or {@code previous} (see the {@link ListIterator}
181      * Javadoc for more details). Since this implementation does not support
182      * {@code add()} or {@code remove()}, {@code set()} may be
183      * called as often as desired.
184      * </p>
185      *
186      * @param obj  The object to set into the array
187      * @throws IllegalStateException if next() has not yet been called.
188      * @throws ClassCastException if the object type is unsuitable for the array
189      */
190     @Override
191     public void set(final E obj) {
192         if (lastItemIndex == -1) {
193             throw new IllegalStateException("must call next() or previous() before a call to set()");
194         }
195         array[lastItemIndex] = obj;
196     }
197 
198 }