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    *      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   * <p>
30   * The iterator implements a {@link #reset} method, allowing the reset of the iterator
31   * back to the start if required.
32   * </p>
33   *
34   * @param <E> the type of elements returned by this iterator.
35   * @see org.apache.commons.collections4.iterators.ObjectArrayIterator
36   * @see java.util.Iterator
37   * @see java.util.ListIterator
38   * @since 3.0
39   */
40  public class ObjectArrayListIterator<E> extends ObjectArrayIterator<E>
41          implements ResettableListIterator<E> {
42  
43      /**
44       * Holds the index of the last item returned by a call to {@code next()}
45       * or {@code previous()}. This is set to {@code -1} if neither method
46       * has yet been invoked. {@code lastItemIndex} is used to implement the
47       * {@link #set} method.
48       */
49      private int lastItemIndex = -1;
50  
51      /**
52       * Constructs an ObjectArrayListIterator that will iterate over the values in the
53       * specified array.
54       *
55       * @param array the array to iterate over
56       * @throws NullPointerException if {@code array} is {@code null}
57       */
58      public ObjectArrayListIterator(final E... array) {
59          super(array);
60      }
61  
62      /**
63       * Constructs an ObjectArrayListIterator that will iterate over the values in the
64       * specified array from a specific start index.
65       *
66       * @param array  the array to iterate over
67       * @param start  the index to start iterating at
68       * @throws NullPointerException if {@code array} is {@code null}
69       * @throws IndexOutOfBoundsException if the start index is out of bounds
70       */
71      public ObjectArrayListIterator(final E[] array, final int start) {
72          super(array, start);
73      }
74  
75      /**
76       * Constructs an ObjectArrayListIterator that will iterate over a range of values
77       * in the specified array.
78       *
79       * @param array  the array to iterate over
80       * @param start  the index to start iterating at
81       * @param end  the index (exclusive) to finish iterating at
82       * @throws IndexOutOfBoundsException if the start or end index is out of bounds
83       * @throws IllegalArgumentException if end index is before the start
84       * @throws NullPointerException if {@code array} is {@code null}
85       */
86      public ObjectArrayListIterator(final E[] array, final int start, final int end) {
87          super(array, start, end);
88      }
89  
90      /**
91       * This iterator does not support modification of its backing array's size, and so will
92       * always throw an {@link UnsupportedOperationException} when this method is invoked.
93       *
94       * @param obj  the object to add
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 java.util.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 java.util.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 }