KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > collections > iterators > LoopingListIterator


1 /*
2  * Copyright 2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.collections.iterators;
17
18 import java.util.List JavaDoc;
19 import java.util.ListIterator JavaDoc;
20 import java.util.NoSuchElementException JavaDoc;
21
22 import org.apache.commons.collections.ResettableListIterator;
23
24 /**
25  * A ListIterator that restarts when it reaches the end or when it
26  * reaches the beginning.
27  * <p>
28  * The iterator will loop continuously around the provided list,
29  * unless there are no elements in the collection to begin with, or
30  * all of the elements have been {@link #remove removed}.
31  * <p>
32  * Concurrent modifications are not directly supported, and for most
33  * collection implementations will throw a
34  * ConcurrentModificationException.
35  *
36  * @since Commons Collections 3.2
37  * @version $Revision: 405920 $ $Date: 2006-05-12 23:48:04 +0100 (Fri, 12 May 2006) $
38  *
39  * @author Eric Crampton <ccesc@eonomine.com>
40  */

41 public class LoopingListIterator implements ResettableListIterator {
42
43     /** The list to base the iterator on */
44     private List JavaDoc list;
45     /** The current list iterator */
46     private ListIterator JavaDoc iterator;
47
48     /**
49      * Constructor that wraps a list.
50      * <p>
51      * There is no way to reset a ListIterator instance without
52      * recreating it from the original source, so the List must be
53      * passed in and a reference to it held.
54      *
55      * @param list the list to wrap
56      * @throws NullPointerException if the list it null
57      */

58     public LoopingListIterator(List JavaDoc list) {
59         if (list == null) {
60             throw new NullPointerException JavaDoc("The list must not be null");
61         }
62         this.list = list;
63         reset();
64     }
65
66     /**
67      * Returns whether this iterator has any more elements.
68      * <p>
69      * Returns false only if the list originally had zero elements, or
70      * all elements have been {@link #remove removed}.
71      *
72      * @return <code>true</code> if there are more elements
73      */

74     public boolean hasNext() {
75         return !list.isEmpty();
76     }
77
78     /**
79      * Returns the next object in the list.
80      * <p>
81      * If at the end of the list, returns the first element.
82      *
83      * @return the object after the last element returned
84      * @throws NoSuchElementException if there are no elements in the list
85      */

86     public Object JavaDoc next() {
87         if (list.isEmpty()) {
88             throw new NoSuchElementException JavaDoc(
89                 "There are no elements for this iterator to loop on");
90         }
91         if (iterator.hasNext() == false) {
92             reset();
93         }
94         return iterator.next();
95     }
96
97     /**
98      * Returns the index of the element that would be returned by a
99      * subsequent call to {@link #next}.
100      * <p>
101      * As would be expected, if the iterator is at the physical end of
102      * the underlying list, 0 is returned, signifying the beginning of
103      * the list.
104      *
105      * @return the index of the element that would be returned if next() were called
106      * @throws NoSuchElementException if there are no elements in the list
107      */

108     public int nextIndex() {
109         if (list.isEmpty()) {
110             throw new NoSuchElementException JavaDoc(
111                 "There are no elements for this iterator to loop on");
112         }
113         if (iterator.hasNext() == false) {
114             return 0;
115         } else {
116             return iterator.nextIndex();
117         }
118     }
119
120     /**
121      * Returns whether this iterator has any more previous elements.
122      * <p>
123      * Returns false only if the list originally had zero elements, or
124      * all elements have been {@link #remove removed}.
125      *
126      * @return <code>true</code> if there are more elements
127      */

128     public boolean hasPrevious() {
129         return !list.isEmpty();
130     }
131
132     /**
133      * Returns the previous object in the list.
134      * <p>
135      * If at the beginning of the list, return the last element. Note
136      * that in this case, traversal to find that element takes linear time.
137      *
138      * @return the object before the last element returned
139      * @throws NoSuchElementException if there are no elements in the list
140      */

141     public Object JavaDoc previous() {
142         if (list.isEmpty()) {
143             throw new NoSuchElementException JavaDoc(
144                 "There are no elements for this iterator to loop on");
145         }
146         if (iterator.hasPrevious() == false) {
147             Object JavaDoc result = null;
148             while (iterator.hasNext()) {
149                 result = iterator.next();
150             }
151             iterator.previous();
152             return result;
153         } else {
154             return iterator.previous();
155         }
156     }
157
158     /**
159      * Returns the index of the element that would be returned by a
160      * subsequent call to {@link #previous}.
161      * <p>
162      * As would be expected, if at the iterator is at the physical
163      * beginning of the underlying list, the list's size minus one is
164      * returned, signifying the end of the list.
165      *
166      * @return the index of the element that would be returned if previous() were called
167      * @throws NoSuchElementException if there are no elements in the list
168      */

169     public int previousIndex() {
170         if (list.isEmpty()) {
171             throw new NoSuchElementException JavaDoc(
172                 "There are no elements for this iterator to loop on");
173         }
174         if (iterator.hasPrevious() == false) {
175             return list.size() - 1;
176         } else {
177             return iterator.previousIndex();
178         }
179     }
180
181     /**
182      * Removes the previously retrieved item from the underlying list.
183      * <p>
184      * This feature is only supported if the underlying list's
185      * {@link List#iterator iterator} method returns an implementation
186      * that supports it.
187      * <p>
188      * This method can only be called after at least one {@link #next}
189      * or {@link #previous} method call. After a removal, the remove
190      * method may not be called again until another {@link #next} or
191      * {@link #previous} has been performed. If the {@link #reset} is
192      * called, then remove may not be called until {@link #next} or
193      * {@link #previous} is called again.
194      *
195      * @throws UnsupportedOperationException if the remove method is
196      * not supported by the iterator implementation of the underlying
197      * list
198      */

199     public void remove() {
200         iterator.remove();
201     }
202
203     /**
204      * Inserts the specified element into the underlying list.
205      * <p>
206      * The element is inserted before the next element that would be
207      * returned by {@link #next}, if any, and after the next element
208      * that would be returned by {@link #previous}, if any.
209      * <p>
210      * This feature is only supported if the underlying list's
211      * {@link List#listIterator} method returns an implementation
212      * that supports it.
213      *
214      * @param obj the element to insert
215      * @throws UnsupportedOperationException if the add method is not
216      * supported by the iterator implementation of the underlying list
217      */

218     public void add(Object JavaDoc obj) {
219         iterator.add(obj);
220     }
221
222     /**
223      * Replaces the last element that was returned by {@link #next} or
224      * {@link #previous}.
225      * <p>
226      * This feature is only supported if the underlying list's
227      * {@link List#listIterator} method returns an implementation
228      * that supports it.
229      *
230      * @param obj the element with which to replace the last element returned
231      * @throws UnsupportedOperationException if the set method is not
232      * supported by the iterator implementation of the underlying list
233      */

234     public void set(Object JavaDoc obj) {
235         iterator.set(obj);
236     }
237
238     /**
239      * Resets the iterator back to the start of the list.
240      */

241     public void reset() {
242         iterator = list.listIterator();
243     }
244
245     /**
246      * Gets the size of the list underlying the iterator.
247      *
248      * @return the current list size
249      */

250     public int size() {
251         return list.size();
252     }
253
254 }
255
Popular Tags