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.collections.iterators;
18  
19  import java.util.ListIterator;
20  import java.util.NoSuchElementException;
21  
22  import org.apache.commons.collections.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   * The iterator implements a {@link #reset} method, allowing the reset of the iterator
31   * back to the start if required.
32   *
33   * @see org.apache.commons.collections.iterators.ObjectArrayIterator
34   * @see java.util.Iterator
35   * @see java.util.ListIterator
36   *
37   * @since 3.0
38   * @version $Id: ObjectArrayListIterator.java 1429905 2013-01-07 17:15:14Z ggregory $
39   */
40  public class ObjectArrayListIterator<E> extends ObjectArrayIterator<E>
41          implements ListIterator<E>, ResettableListIterator<E> {
42  
43      /**
44       * Holds the index of the last item returned by a call to <code>next()</code> 
45       * or <code>previous()</code>. This is set to <code>-1</code> if neither method
46       * has yet been invoked. <code>lastItemIndex</code> is used to to implement the
47       * {@link #set} method.
48       */
49      protected int lastItemIndex = -1;
50  
51      /**
52       * Constructor for use with <code>setArray</code>.
53       * <p>
54       * Using this constructor, the iterator is equivalent to an empty iterator
55       * until {@link #setArray} is  called to establish the array to iterate over.
56       */
57      public ObjectArrayListIterator() {
58          super();
59      }
60  
61      /**
62       * Constructs an ObjectArrayListIterator that will iterate over the values in the
63       * specified array.
64       *
65       * @param array the array to iterate over
66       * @throws NullPointerException if <code>array</code> is <code>null</code>
67       */
68      public ObjectArrayListIterator(final E... array) {
69          super(array);
70      }
71  
72      /**
73       * Constructs an ObjectArrayListIterator that will iterate over the values in the
74       * specified array from a specific start index.
75       *
76       * @param array  the array to iterate over
77       * @param start  the index to start iterating at
78       * @throws NullPointerException if <code>array</code> is <code>null</code>
79       * @throws IndexOutOfBoundsException if the start index is out of bounds
80       */
81      public ObjectArrayListIterator(final E[] array, final int start) {
82          super(array, start);
83      }
84      
85      /**
86       * Construct an ObjectArrayListIterator that will iterate over a range of values 
87       * in the specified array.
88       *
89       * @param array  the array to iterate over
90       * @param start  the index to start iterating at
91       * @param end  the index (exclusive) to finish iterating at
92       * @throws IndexOutOfBoundsException if the start or end index is out of bounds
93       * @throws IllegalArgumentException if end index is before the start
94       * @throws NullPointerException if <code>array</code> is <code>null</code>
95       */
96      public ObjectArrayListIterator(final E[] array, final int start, final int end) {
97          super(array, start, end);
98      }
99  
100     // ListIterator interface
101     //-------------------------------------------------------------------------
102 
103     /**
104      * Returns true if there are previous elements to return from the array.
105      *
106      * @return true if there is a previous element to return
107      */
108     public boolean hasPrevious() {
109         return this.index > this.startIndex;
110     }
111 
112     /**
113      * Gets the previous element from the array.
114      * 
115      * @return the previous element
116      * @throws NoSuchElementException if there is no previous element
117      */
118     public E previous() {
119         if (hasPrevious() == false) {
120             throw new NoSuchElementException();
121         }
122         this.lastItemIndex = --this.index;
123         return this.array[this.index];
124     }
125 
126     /**
127      * Gets the next element from the array.
128      * 
129      * @return the next element
130      * @throws NoSuchElementException if there is no next element
131      */
132     @Override
133     public E next() {
134         if (hasNext() == false) {
135             throw new NoSuchElementException();
136         }
137         this.lastItemIndex = this.index;
138         return this.array[this.index++];
139     }
140 
141     /**
142      * Gets the next index to be retrieved.
143      * 
144      * @return the index of the item to be retrieved next
145      */
146     public int nextIndex() {
147         return this.index - this.startIndex;
148     }
149 
150     /**
151      * Gets the index of the item to be retrieved if {@link #previous()} is called.
152      * 
153      * @return the index of the item to be retrieved next
154      */
155     public int previousIndex() {
156         return this.index - this.startIndex - 1;
157     }
158 
159     /**
160      * This iterator does not support modification of its backing array's size, and so will
161      * always throw an {@link UnsupportedOperationException} when this method is invoked.
162      *
163      * @param obj  the object to add
164      * @throws UnsupportedOperationException always thrown.
165      */
166     public void add(final E obj) {
167         throw new UnsupportedOperationException("add() method is not supported");
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 ListIterator} implementations that support <code>add()</code>
177      * and <code>remove()</code> only allow <code>set()</code> to be called once per call 
178      * to <code>next()</code> or <code>previous</code> (see the {@link ListIterator}
179      * javadoc for more details). Since this implementation does not support 
180      * <code>add()</code> or <code>remove()</code>, <code>set()</code> 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     public void set(final E obj) {
188         if (this.lastItemIndex == -1) {
189             throw new IllegalStateException("must call next() or previous() before a call to set()");
190         }
191 
192         this.array[this.lastItemIndex] = obj;
193     }
194 
195     /**
196      * Resets the iterator back to the start index.
197      */
198     @Override
199     public void reset() {
200         super.reset();
201         this.lastItemIndex = -1;
202     }
203 
204 }