Class LazySet<E>

Type Parameters:
E - the type of elements in the set.
All Implemented Interfaces:
Iterable<E>, Collection<E>, Set<E>
Direct Known Subclasses:
AuthorityFactories, Providers

public class LazySet<E> extends SetOfUnknownSize<E>
An immutable set built from an iterator, which will be filled only when needed. This implementation does not check if all elements in the iterator are really unique; we assume that this condition was already verified by the caller.

One usage of LazySet is to workaround a ServiceLoader bug which blocks usage of two Iterator instances together: the first iteration must be fully completed or abandoned before we can start a new iteration. See DefaultMathTransformFactory().

Some usages for this class are to prepend some values before the elements given by the source Iterable, or to replace some values when they are loaded. It may also be used for creating filtered sets when used together with CollectionsExt.filter(…).

This class is not thread-safe. Synchronization, if desired, shall be done by the caller.

Since:
0.6
Version:
0.8
  • Field Details

    • service

      private final Class<E> service
      The type of service to request with ServiceLoader, or null if unknown.
    • sourceIterator

      private Iterator<? extends E> sourceIterator
      The iterator to use for filling this set, or null if the iteration did not started yet or is finished. Those two cases can be distinguished by looking whether the cachedElements array is null or not.
    • cachedElements

      private E[] cachedElements
      The elements that we cached so far, or null if the iteration did not started yet. After the iteration started, this array will grow as needed.
      See Also:
    • numCached

      private int numCached
      The number of valid elements in the cachedElements array. This counter will be incremented as long as there is more elements returned by sourceIterator.
  • Constructor Details

    • LazySet

      public LazySet(Class<E> service)
      Constructs a set to be filled by the elements from the specified source. Iteration will start only when first needed, and at most one iteration will be performed (unless reload() is invoked).
      Parameters:
      service - the type of service to request with ServiceLoader.
    • LazySet

      public LazySet(Iterator<? extends E> iterator)
      Constructs a set to be filled using the specified iterator. Iteration with the given iterator will occur only when needed.
      Parameters:
      iterator - the iterator to use for filling this set.
  • Method Details

    • reload

      public void reload()
      Notifies this LazySet that it should re-fetch the elements from the source given at construction time.
    • initialValues

      protected E[] initialValues()
      Hook for subclasses that want to prepend some values before the source Iterable. This method is invoked only when first needed. It is safe to return a shared array since LazySet will not write in that array (LazySet will create a new array if it needs to add more values).
      Returns:
      values to prepend before the source Iterable, or null if none.
      Since:
      0.7
    • createCache

      private boolean createCache()
      Creates the cachedElements array. This array will contain the elements given by initialValues() if that method returned a non-null and non-empty array.
      Returns:
      true if initialValues() initialized the set with at least one value.
    • canPullMore

      private boolean canPullMore()
      Returns true if the sourceIterator is non-null and have more elements to return, or if we initialized the cache with some elements declared by initialValues().
    • isEmpty

      public final boolean isEmpty()
      Tests if this set has no element.
      Specified by:
      isEmpty in interface Collection<E>
      Specified by:
      isEmpty in interface Set<E>
      Overrides:
      isEmpty in class SetOfUnknownSize<E>
      Returns:
      true if this set has no element.
    • size

      public final int size()
      Returns the number of elements in this set. Invoking this method forces the set to immediately iterates through all remaining elements.
      Specified by:
      size in interface Collection<E>
      Specified by:
      size in interface Set<E>
      Overrides:
      size in class SetOfUnknownSize<E>
      Returns:
      number of elements in the iterator.
    • next

      protected E next(Iterator<? extends E> it)
      Returns the next element from the given iterator. Default implementation returns Iterator.next(). Subclasses may override if they need to apply additional processing. For example, this method can be used for skipping data, but this approach works only if we have the guarantee that another element exists after the skipped one (because LazySet will not invoke Iterator.hasNext() again).
      Parameters:
      it - the iterator from which to get a next value.
      Returns:
      the next value (may be null).
    • cache

      protected void cache(E element)
      Caches a new element. Subclasses can override this method if they want to substitute the given value by another value.
      Parameters:
      element - the element to add to the cache.
    • cached

      protected final List<E> cached()
      Returns an unmodifiable view over the elements cached so far. The returned list does not contain any elements that were not yet fetched from the source.
      Returns:
      the elements cached so far.
    • exists

      final boolean exists(int index)
      Returns true if an element exists at the given index. The element is not loaded immediately.

      NOTE: This method is for use by iterators only. It is not suited for more general usage since it does not check for negative index and for skipped elements.

    • get

      final E get(int index)
      Returns the element at the specified position in this set.
      Parameters:
      index - the index at which to get an element.
      Returns:
      the element at the requested index.
    • iterator

      public final Iterator<E> iterator()
      Returns an iterator over the elements contained in this set. This is not the same iterator than the one given to the constructor.
      Specified by:
      iterator in interface Collection<E>
      Specified by:
      iterator in interface Iterable<E>
      Specified by:
      iterator in interface Set<E>
      Specified by:
      iterator in class AbstractCollection<E>
      Returns:
      an iterator over the elements in this set.