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