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