How to Convert Iterable to Collection

Easy way to convert Iterable to Collection

With Guava you can use Lists.newArrayList(Iterable) or Sets.newHashSet(Iterable), among other similar methods. This will of course copy all the elements in to memory. If that isn't acceptable, I think your code that works with these ought to take Iterable rather than Collection. Guava also happens to provide convenient methods for doing things you can do on a Collection using an Iterable (such as Iterables.isEmpty(Iterable) or Iterables.contains(Iterable, Object)), but the performance implications are more obvious.

Convert Iterator to List

Better use a library like Guava:

import com.google.common.collect.Lists;

Iterator<Element> myIterator = ... //some iterator
List<Element> myList = Lists.newArrayList(myIterator);

Another Guava example:

ImmutableList.copyOf(myIterator);

or Apache Commons Collections:

import org.apache.commons.collections.IteratorUtils;

Iterator<Element> myIterator = ...//some iterator

List<Element> myList = IteratorUtils.toList(myIterator);

Scala convert Iterable or collection.Seq to collection.immutable.Seq

Use the to method to convert between arbitrary collection types in Scala 2.10:

scala> Array(1, 2, 3).toSeq
res0: Seq[Int] = WrappedArray(1, 2, 3)

scala> Array(1, 2, 3).to[collection.immutable.Seq]
res1: scala.collection.immutable.Seq[Int] = Vector(1, 2, 3)

Collection to Iterable

A Collection is an Iterable.

So you can write:

public static void main(String args[]) {
List<String> list = new ArrayList<String>();
list.add("a string");

Iterable<String> iterable = list;
for (String s : iterable) {
System.out.println(s);
}
}

Convert Iterable to Stream using Java 8 JDK

There's a much better answer than using spliteratorUnknownSize directly, which is both easier and gets a better result. Iterable has a spliterator() method, so you should just use that to get your spliterator. In the worst case, it's the same code (the default implementation uses spliteratorUnknownSize), but in the more common case, where your Iterable is already a collection, you'll get a better spliterator, and therefore better stream performance (maybe even good parallelism). It's also less code:

StreamSupport.stream(iterable.spliterator(), false)
.filter(...)
.moreStreamOps(...);

As you can see, getting a stream from an Iterable (see also this question) is not very painful.

Initializing a Set with an Iterable

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(); }
}

IterableElement cannot be cast to ListElement - Isn't `List` a type of `Iterable`?

Yes, List<T> extends Iterable<T>, but that doesn't mean that you can cast from any Iterable<T> to List<T> - only when the value actually refers to an instance of a type of List<T>. It's entirely possible to implement Iterable<T> without implementing the rest of the List<T> interface... in that case, what would you expect to happen?

To put it in simpler terms, let's change Iterable<T> to Object and List<T> to String. String extends Object, so you can try to cast from Object to String... but the cast will only succeed at execution time if the reference actually refers to a String (or is null).



Related Topics



Leave a reply



Submit