001/*
002 * Copyright (c) 2016-2018 Chris K Wensel <chris@wensel.net>. All Rights Reserved.
003 *
004 * Project and contact information: http://www.cascading.org/
005 *
006 * This file is part of the Cascading project.
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *     http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020
021package cascading.util;
022
023import java.util.Arrays;
024import java.util.Iterator;
025import java.util.LinkedList;
026
027/**
028 *
029 */
030public abstract class LazyIterable<V, T> implements Iterable<T>
031  {
032  LinkedList<T> cache;
033  Iterable<V> iterable;
034
035  public LazyIterable( V... values )
036    {
037    this( Arrays.asList( values ) );
038    }
039
040  public LazyIterable( boolean enableCache, V... values )
041    {
042    this( enableCache, Arrays.asList( values ) );
043    }
044
045  public LazyIterable( Iterable<V> iterable )
046    {
047    this( true, iterable );
048    }
049
050  public LazyIterable( boolean enableCache, Iterable<V> iterable )
051    {
052    if( enableCache )
053      this.cache = new LinkedList<>();
054
055    this.iterable = iterable;
056    }
057
058  @Override
059  public Iterator<T> iterator()
060    {
061    if( cache != null && !cache.isEmpty() )
062      return cache.iterator();
063
064    final Iterator<V> iterator = iterable.iterator();
065
066    return new Iterator<T>()
067      {
068      @Override
069      public boolean hasNext()
070        {
071        return iterator.hasNext();
072        }
073
074      @Override
075      public T next()
076        {
077        T converted = convert( iterator.next() );
078
079        if( cache != null )
080          cache.add( converted );
081
082        return converted;
083        }
084
085      @Override
086      public void remove()
087        {
088        iterator.remove();
089        }
090      };
091    }
092
093  protected abstract T convert( V next );
094  }