1
2 package eu.simuline.util;
3
4 import java.util.List;
5 import java.util.Iterator;
6 import java.util.NoSuchElementException; // for javadoc only
7
8 /**
9 * An iterator over a {@link CyclicList}.
10 * <code>CyclicIterator</code> corresponds with <code>CyclicList</code>s
11 * as <code>Iterator</code>s or <code>ListIterator</code>s do
12 * with <code>List</code>s.
13 *
14 * @param <E>
15 * the class of the elements to iterate over.
16 *
17 * @see CyclicList
18 * @see java.util.ListIterator
19 * @author <a href="mailto:ernst.reissner@simuline.eu">Ernst Reissner</a>
20 * @version 1.0
21 */
22 public interface CyclicIterator<E> extends Iterator<E> {
23
24 /*------------------------------------------------------------------*/
25 /* Query Operations (boolean and others) */
26 /*------------------------------------------------------------------*/
27
28 /**
29 * Returns the cursor of this iterator
30 * immediately after it has been created
31 * (if not modified since then which is currently not possible.).
32 *
33 * @return
34 * the cursor of this iterator
35 * immediately after it has been created
36 * (if not modified since then).
37 * @see CyclicList#cyclicIterator(int)
38 */
39 int getFirstIndex();
40
41 /**
42 * Returns the current cursor of this iterator.
43 *
44 * @return
45 * the current cursor of this iterator.
46 */
47 int getIndex();
48
49 /**
50 * Returns the cyclic list to which this iterator points.
51 * Contract:
52 * <code>cyclicList.cyclicIterator(int).getCyclicList() ==
53 * cyclicList</code> again.
54 *
55 * @return
56 * the cyclic list to which this iterator points.
57 * This may be empty but it may not be <code>null</code>.
58 * @see CyclicList#cyclicIterator(int)
59 */
60 CyclicList<E> getCyclicList();
61
62 /**
63 * Returns <code>true</code> if the iteration has more elements.
64 * (In other words, returns <code>true</code>
65 * if <code>next</code> would return an element
66 * rather than throwing an exception.)
67 *
68 * @return
69 * <code>true</code> if the iterator has more elements.
70 */
71 boolean hasNext();
72
73 /**
74 * Returns the next element in the interation.
75 * This method may be called repeatedly to iterate through the list,
76 * or intermixed with calls to <code>previous</code> to go back and forth.
77 * (Note that alternating calls to <code>next</code>
78 * and <code>previous</code>
79 * will return the same element repeatedly.)
80 *
81 * @return
82 * the next element in the interation.
83 * @exception NoSuchElementException
84 * iteration has no more elements.
85 */
86 E next();
87
88 /**
89 * Returns <code>true</code> if this iterator has more elements when
90 * traversing the cyclic list in the reverse direction.
91 * (In other words, returns <code>true</code>
92 * if <code>previous</code> would return an element
93 * rather than throwing an exception.)
94 *
95 * @return
96 * <code>true</code> if the list iterator has more elements
97 * when traversing the list in the reverse direction.
98 */
99 boolean hasPrev();
100
101 /**
102 * Returns the previous element in the cyclic list.
103 * This method may be called repeatedly
104 * to iterate through the list backwards,
105 * or intermixed with calls to <code>next</code> to go back and forth.
106 * (Note that alternating calls
107 * to <code>next</code> and <code>previous</code>
108 * will return the same element repeatedly.)
109 *
110 * @return
111 * the previous element in the list.
112 * @throws NoSuchElementException
113 * if the iteration has no previous element.
114 */
115 E previous();
116
117 /*
118 * Returns the index of the element
119 * that would be returned by a subsequent call to <code>next</code>.
120 *
121 * @return
122 * the index of the element
123 * that would be returned by a subsequent call to <code>next</code>.
124 * The range is <code>0,...,size()-1</code>.
125 */
126 //int nextIndex();
127
128 /*
129 * Returns the index of the element
130 * that would be returned by a subsequent call to <code>previous</code>.
131 *
132 * @return
133 * the index of the element
134 * that would be returned by a subsequent call to <code>previous</code>.
135 * The range is <code>0,...,size()-1</code>.
136 */
137 //int previousIndex();
138
139 /**
140 * Returns the (non-negative) index
141 * of the next object returned by <code>next</code>
142 * which equals the given one, if possible;
143 * otherwise returns <code>-1</code>.
144 *
145 * @param obj
146 * an object.
147 * @return
148 * <ul>
149 * <li>
150 * the index minimal index
151 * <code>ind in {0,...,this.list.size()-1}</code>
152 * satisfying <code>obj.equals(this.list.get(ind))</code>
153 * if possible;
154 * <li>
155 * <code>-1</code> if there is no such index.
156 * </ul>
157 */
158 int getNextIndexOf(E obj);
159
160 /*------------------------------------------------------------------*/
161 /* Modification Operations */
162 /*------------------------------------------------------------------*/
163
164
165 /**
166 * Sets the given index as cursor of this iterator.
167 * Consider the case first
168 * that the underlying list {@link #getCyclicList} is not empty.
169 * Then <code>it.setIndex(index); return it.getIndex();</code>
170 * returns <code>index</code> again
171 * up to <code>it.getCyclicList().size()</code>.
172 * For <code>it.getCyclicList().isEmpty()</code>,
173 * this method does not modify this iterator.
174 *
175 * @param index
176 * an arbitrary <code>int</code> value,
177 * which may also be negative.
178 */
179 void setIndex(int index);
180
181 /**
182 * Inserts the specified element into the underlying cyclic list
183 * (optional operation).
184 * The element is inserted immediately before the next element
185 * that would be returned by <code>next</code>, if any,
186 * and after the next element
187 * that would be returned by <code>previous</code>, if any.
188 * (If the cyclic list is empty,
189 * the new element becomes the sole element on the cyclic list.)
190 * <p>
191 * The new element is inserted before the implicit cursor:
192 * a subsequent call to <code>next</code> would be unaffected,
193 * and a subsequent call to <code>previous</code>
194 * would return the new element.
195 * (This call increases by one the value that would be returned by a call
196 * to <code>nextIndex</code> or <code>previousIndex</code>.)
197 *
198 * @param obj
199 * the element to be inserted.
200 * @exception UnsupportedOperationException
201 * if the <code>add</code> method is not supported by this iterator.
202 * @exception ClassCastException
203 * if the class of the specified element
204 * prevents it from being added to the underlying cyclic list.
205 * @exception IllegalArgumentException
206 * if some aspect of this element
207 * prevents it from being added to the underlying cyclic list.
208 * @see #addAll
209 */
210 void add(E obj);
211
212 /**
213 * Inserts the specified list into the underlying cyclic list
214 * (optional operation).
215 * The list is inserted immediately before the next element
216 * that would be returned by <code>next</code>, if any,
217 * and after the next element
218 * that would be returned by <code>previous</code>, if any.
219 * (If the cyclic list is empty,
220 * the new cyclic list comprises the given list.)
221 * <p>
222 * The given list is inserted before the implicit cursor:
223 * a subsequent call to <code>next</code> would be unaffected,
224 * and a subsequent call to <code>previous</code>
225 * would return the given list in reversed order.
226 * (This call increases by <code>list.size()</code>
227 * the value that would be returned by a call
228 * to <code>nextIndex</code> or <code>previousIndex</code>.)
229 * <p>
230 * If <code>list.size()</code> contains a single element <code>e</code>,
231 * <code>addAll(list)</code> is equivalent with <code>add(e)</code>.
232 *
233 * @param list
234 * the list to be inserted.
235 * @throws UnsupportedOperationException
236 * if the <code>add</code> method is not supported by this iterator.
237 * @throws ClassCastException
238 * if the class of the an element in the specified list
239 * prevents it from being added to the underlying list.
240 * @throws IllegalArgumentException
241 * if some aspect of the an element in the specified list
242 * prevents it from being added to the underlying list.
243 * @see #add
244 */
245 void addAll(List<? extends E> list);
246
247 /**
248 * Replaces the last element
249 * returned by <code>next</code> or <code>previous</code>
250 * with the specified element (optional operation).
251 * This call can be made only
252 * if neither <code>ListIterator.remove</code> nor <code>add</code>
253 * have been called after the last call to
254 * <code>next</code> or <code>previous</code>.
255 *
256 * @param obj
257 * the element with which to replace the last element
258 * returned by next or previous.
259 * @exception UnsupportedOperationException
260 * if the <code>set</code> operation
261 * is not supported by this iterator.
262 * @exception ClassCastException
263 * if the class of the specified element
264 * prevents it from being added to this cyclic list.
265 * @exception IllegalArgumentException
266 * if some aspect of the specified element
267 * prevents it from being added to this list.
268 * @exception IllegalStateException
269 * if neither <code>next</code> nor <code>previous</code>
270 * have been called,
271 * or <code>remove</code> or <code>add</code> have been called
272 * after the last call to <code>next</code> or <code>previous</code>.
273 */
274 void set(E obj);
275
276 /**
277 * Removes from the underlying <code>CyclicList</code>
278 * the last element returned by <code>next</code> or <code>previous</code>
279 * (optional operation).
280 * This method can be called only once
281 * per call to <code>next</code> or <code>previous</code>.
282 * It can be made only if <code>add</code> has not been called after
283 * the last call to <code>next</code> or <code>previous</code>.
284 *
285 * @exception UnsupportedOperationException
286 * if the <code>remove</code> operation
287 * is not supported by this CyclicIterator.
288 * @exception IllegalStateException
289 * if neither <code>next</code> nor <code>previous</code>
290 * have been called,
291 * or <code>remove</code> or <code>add</code> have been called
292 * after the last call to <code>next</code> or <code>previous</code>.
293 */
294 void remove();
295
296 /**
297 * Reinitialize this iterator without changing the cursor
298 * but such that all elements of the corresponding cyclic list
299 * may be accessed successively through {@link #next}.
300 * On the other hand, {@link #previous} throws an exception.
301 */
302 void refresh();
303
304 //boolean equals(Object other);
305 boolean retEquals(CyclicIterator<?> other);
306
307 /**
308 * Returns <code>false</code> if <code>other</code> is not an instance of
309 * <code>CyclicIterator</code>.
310 * The implementation of this interface should not play a role.
311 *
312 * @param other
313 * another <code>Object</code>.
314 * @return
315 * <code>false</code> if <code>other</code> is not an instance of
316 * <code>CyclicIterator</code>.
317 * The implementation of this interface should not play a role.
318 */
319 boolean equals(Object other);
320
321 double dist(CyclicIterator<E> other);
322 }