IteratorTransform.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.geometry.core.internal;

  18. import java.util.Collection;
  19. import java.util.Deque;
  20. import java.util.Iterator;
  21. import java.util.LinkedList;
  22. import java.util.NoSuchElementException;

  23. /** Class that wraps another iterator, converting each input iterator value into
  24.  * one or more output iterator values.
  25.  * @param <I> Input iterator type
  26.  * @param <T> Output iterator type
  27.  */
  28. public abstract class IteratorTransform<I, T> implements Iterator<T> {

  29.     /** Input iterator instance that supplies the input values for this instance. */
  30.     private final Iterator<I> inputIterator;

  31.     /** Output value queue. */
  32.     private final Deque<T> outputQueue = new LinkedList<>();

  33.     /** Create a new instance that uses the given iterator as the input source.
  34.      * @param inputIterator iterator supplying input values
  35.      */
  36.     protected IteratorTransform(final Iterator<I> inputIterator) {
  37.         this.inputIterator = inputIterator;
  38.     }

  39.     /** {@inheritDoc} */
  40.     @Override
  41.     public boolean hasNext() {
  42.         return loadNextOutput();
  43.     }

  44.     /** {@inheritDoc} */
  45.     @Override
  46.     public T next() {
  47.         if (outputQueue.isEmpty()) {
  48.             throw new NoSuchElementException();
  49.         }

  50.         return outputQueue.removeFirst();
  51.     }

  52.     /** Load the next output values into the output queue. Returns true if the output queue
  53.      * contains more entries.
  54.      * @return true if more output values are available
  55.      */
  56.     private boolean loadNextOutput() {
  57.         while (outputQueue.isEmpty() && inputIterator.hasNext()) {
  58.             acceptInput(inputIterator.next());
  59.         }

  60.         return !outputQueue.isEmpty();
  61.     }

  62.     /** Add a value to the output queue.
  63.      * @param value value to add to the output queue
  64.      */
  65.     protected void addOutput(final T value) {
  66.         outputQueue.add(value);
  67.     }

  68.     /** Add multiple values to the output queue.
  69.      * @param values values to add to the output queue
  70.      */
  71.     protected void addAllOutput(final Collection<T> values) {
  72.         outputQueue.addAll(values);
  73.     }

  74.     /** Accept a value from the input iterator. This method should take
  75.      * the input value and add one or more values to the output queue.
  76.      * @param input value from the input iterator
  77.      */
  78.     protected abstract void acceptInput(I input);
  79. }