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   * <code>SingletonIterator</code> is an {@link ListIterator} over a single 
26   * object instance.
27   *
28   * @since 2.1
29   * @version $Id: SingletonListIterator.java 1429905 2013-01-07 17:15:14Z ggregory $
30   */
31  public class SingletonListIterator<E> implements ListIterator<E>, ResettableListIterator<E> {
32  
33      private boolean beforeFirst = true;
34      private boolean nextCalled = false;
35      private boolean removed = false;
36      private E object;
37  
38      /**
39       * Constructs a new <code>SingletonListIterator</code>.
40       *
41       * @param object  the single object to return from the iterator
42       */
43      public SingletonListIterator(final E object) {
44          super();
45          this.object = object;
46      }
47  
48      /**
49       * Is another object available from the iterator?
50       * <p>
51       * This returns true if the single object hasn't been returned yet.
52       * 
53       * @return true if the single object hasn't been returned yet
54       */
55      public boolean hasNext() {
56          return beforeFirst && !removed;
57      }
58  
59      /**
60       * Is a previous object available from the iterator?
61       * <p>
62       * This returns true if the single object has been returned.
63       * 
64       * @return true if the single object has been returned
65       */
66      public boolean hasPrevious() {
67          return !beforeFirst && !removed;
68      }
69  
70      /**
71       * Returns the index of the element that would be returned by a subsequent
72       * call to <tt>next</tt>.
73       *
74       * @return 0 or 1 depending on current state. 
75       */
76      public int nextIndex() {
77          return beforeFirst ? 0 : 1;
78      }
79  
80      /**
81       * Returns the index of the element that would be returned by a subsequent
82       * call to <tt>previous</tt>. A return value of -1 indicates that the iterator is currently at
83       * the start.
84       *
85       * @return 0 or -1 depending on current state. 
86       */
87      public int previousIndex() {
88          return beforeFirst ? -1 : 0;
89      }
90  
91      /**
92       * Get the next object from the iterator.
93       * <p>
94       * This returns the single object if it hasn't been returned yet.
95       *
96       * @return the single object
97       * @throws NoSuchElementException if the single object has already 
98       *    been returned
99       */
100     public E next() {
101         if (!beforeFirst || removed) {
102             throw new NoSuchElementException();
103         }
104         beforeFirst = false;
105         nextCalled = true;
106         return object;
107     }
108 
109     /**
110      * Get the previous object from the iterator.
111      * <p>
112      * This returns the single object if it has been returned.
113      *
114      * @return the single object
115      * @throws NoSuchElementException if the single object has not already 
116      *    been returned
117      */
118     public E previous() {
119         if (beforeFirst || removed) {
120             throw new NoSuchElementException();
121         }
122         beforeFirst = true;
123         return object;
124     }
125 
126     /**
127      * Remove the object from this iterator.
128      * @throws IllegalStateException if the <tt>next</tt> or <tt>previous</tt> 
129      *        method has not yet been called, or the <tt>remove</tt> method 
130      *        has already been called after the last call to <tt>next</tt>
131      *        or <tt>previous</tt>.
132      */
133     public void remove() {
134         if(!nextCalled || removed) {
135             throw new IllegalStateException();
136         } else {
137             object = null;
138             removed = true;
139         }
140     }
141     
142     /**
143      * Add always throws {@link UnsupportedOperationException}.
144      *
145      * @param obj  the object to add
146      * @throws UnsupportedOperationException always
147      */
148     public void add(final E obj) {
149         throw new UnsupportedOperationException("add() is not supported by this iterator");
150     }
151     
152     /**
153      * Set sets the value of the singleton.
154      *
155      * @param obj  the object to set
156      * @throws IllegalStateException if <tt>next</tt> has not been called 
157      *          or the object has been removed
158      */
159     public void set(final E obj) {
160         if (!nextCalled || removed) {
161             throw new IllegalStateException();
162         }
163         this.object = obj;
164     }
165     
166     /**
167      * Reset the iterator back to the start.
168      */
169     public void reset() {
170         beforeFirst = true;
171         nextCalled = false;
172     }
173     
174 }