Search code examples
javasetiterable

Initializing a Set with an Iterable


I want to initialize a Set Implementation (HashSet) in Java with an Iterable. However, the constructor of HashSet doesn't accept Iterables, but only Collections type objects.

Is there a way to convert from Iterable to some subtype of Collections.


Solution

  • HashSet constructor relies on more than what Iterable offers: it wants to know the size of the collection up front in order to optimally construct the underlying HashMap. If you have a true, austere Iterable, which doesn't know its size, then you'll have to realize the Iterable up front by turning it into a regular Collection in any of a number of obvious ways.

    If, on the other hand, you have a richer object that already knows its size, then it would pay to create a minimalist adapter class that wraps your Iterable into a collection, implementing just size in addition to forwarding the call to iterator.

    public class IterableCollection<T> implements Collection<T>
    {
       private final Iterable<T> iterable;
    
       public IterableCollection(Iterable<T> it) { this.iterable = it; }
    
       @Override public Iterator<T> iterator() { return iterable.iterator(); }
    
       @Override public int size() { return ... custom code to determine size ... }
    
       @Override .... all others ... { throw new UnsupportedOperationException(); }
    }