SingletonListIterator.java

  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. import java.util.NoSuchElementException;

  19. import org.apache.commons.collections4.ResettableListIterator;

  20. /**
  21.  * {@code SingletonIterator} is an {@link java.util.ListIterator} over a single
  22.  * object instance.
  23.  *
  24.  * @param <E> the type of elements returned by this iterator.
  25.  * @since 2.1
  26.  */
  27. public class SingletonListIterator<E> implements ResettableListIterator<E> {

  28.     private boolean beforeFirst = true;
  29.     private boolean nextCalled;
  30.     private boolean removed;
  31.     private E object;

  32.     /**
  33.      * Constructs a new {@code SingletonListIterator}.
  34.      *
  35.      * @param object  the single object to return from the iterator
  36.      */
  37.     public SingletonListIterator(final E object) {
  38.         this.object = object;
  39.     }

  40.     /**
  41.      * Add always throws {@link UnsupportedOperationException}.
  42.      *
  43.      * @param obj  the object to add
  44.      * @throws UnsupportedOperationException always
  45.      */
  46.     @Override
  47.     public void add(final E obj) {
  48.         throw new UnsupportedOperationException("add() is not supported by this iterator");
  49.     }

  50.     /**
  51.      * Is another object available from the iterator?
  52.      * <p>
  53.      * This returns true if the single object hasn't been returned yet.
  54.      *
  55.      * @return true if the single object hasn't been returned yet
  56.      */
  57.     @Override
  58.     public boolean hasNext() {
  59.         return beforeFirst && !removed;
  60.     }

  61.     /**
  62.      * Is a previous object available from the iterator?
  63.      * <p>
  64.      * This returns true if the single object has been returned.
  65.      *
  66.      * @return true if the single object has been returned
  67.      */
  68.     @Override
  69.     public boolean hasPrevious() {
  70.         return !beforeFirst && !removed;
  71.     }

  72.     /**
  73.      * Gets the next object from the iterator.
  74.      * <p>
  75.      * This returns the single object if it hasn't been returned yet.
  76.      *
  77.      * @return the single object
  78.      * @throws NoSuchElementException if the single object has already
  79.      *    been returned
  80.      */
  81.     @Override
  82.     public E next() {
  83.         if (!beforeFirst || removed) {
  84.             throw new NoSuchElementException();
  85.         }
  86.         beforeFirst = false;
  87.         nextCalled = true;
  88.         return object;
  89.     }

  90.     /**
  91.      * Returns the index of the element that would be returned by a subsequent
  92.      * call to {@code next}.
  93.      *
  94.      * @return 0 or 1 depending on current state.
  95.      */
  96.     @Override
  97.     public int nextIndex() {
  98.         return beforeFirst ? 0 : 1;
  99.     }

  100.     /**
  101.      * Gets the previous object from the iterator.
  102.      * <p>
  103.      * This returns the single object if it has been returned.
  104.      *
  105.      * @return the single object
  106.      * @throws NoSuchElementException if the single object has not already
  107.      *    been returned
  108.      */
  109.     @Override
  110.     public E previous() {
  111.         if (beforeFirst || removed) {
  112.             throw new NoSuchElementException();
  113.         }
  114.         beforeFirst = true;
  115.         return object;
  116.     }

  117.     /**
  118.      * Returns the index of the element that would be returned by a subsequent
  119.      * call to {@code previous}. A return value of -1 indicates that the iterator is currently at
  120.      * the start.
  121.      *
  122.      * @return 0 or -1 depending on current state.
  123.      */
  124.     @Override
  125.     public int previousIndex() {
  126.         return beforeFirst ? -1 : 0;
  127.     }

  128.     /**
  129.      * Remove the object from this iterator.
  130.      * @throws IllegalStateException if the {@code next} or {@code previous}
  131.      *        method has not yet been called, or the {@code remove} method
  132.      *        has already been called after the last call to {@code next}
  133.      *        or {@code previous}.
  134.      */
  135.     @Override
  136.     public void remove() {
  137.         if (!nextCalled || removed) {
  138.             throw new IllegalStateException();
  139.         }
  140.         object = null;
  141.         removed = true;
  142.     }

  143.     /**
  144.      * Reset the iterator back to the start.
  145.      */
  146.     @Override
  147.     public void reset() {
  148.         beforeFirst = true;
  149.         nextCalled = false;
  150.     }

  151.     /**
  152.      * Sets sets the value of the singleton.
  153.      *
  154.      * @param object  the object to set
  155.      * @throws IllegalStateException if {@code next} has not been called
  156.      *          or the object has been removed
  157.      */
  158.     @Override
  159.     public void set(final E object) {
  160.         if (!nextCalled || removed) {
  161.             throw new IllegalStateException();
  162.         }
  163.         this.object = object;
  164.     }

  165. }