Take the 2-minute tour ×

In my application I use 3rd party library (Spring Data for MongoDb to be exact).

Methods of this library return Iterable<T>, while the rest of my code expects Collection<T>.

Is there any utility method somewhere that will let me quickly convert one to the other. I would like to avoid making a banch of foreach loops in my code for such a simple thing.

share|improve this question
Any utiliy method for performing the operation is bound to iterate of the collection anyway, so you can't expect any performance gain. But if you're just looking for syntactic sugar I would go for Guava or perhaps Apache Collections. –  Sebastian Ganslandt Jun 20 '11 at 20:12
"is bound to iterate of the collection anyway", -- no, it's not. See my answer for details. –  aioobe Jun 20 '11 at 20:31

12 Answers 12

up vote 91 down vote accepted

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.

share|improve this answer
Does it iterate through all elements directly? I.e., is Lists.newArrayList(Iterable).clear() a linear or constant time operation? –  aioobe Jun 20 '11 at 20:13
@aioobe: It creates a copy of the iterable. It wasn't specified that a view was desired, and given that most of the methods on Collection either can't be implemented for a view of an Iterable or won't be efficient, it doesn't make much sense to me to do that. –  ColinD Jun 20 '11 at 20:23
@ColinD what if I want a view ? Actually, what I want is a Collection view that is the result of appending a source Collection with another element. I can use Iterables.concat() but that gives an Iterable, not a Collection :( –  Hendy Irawan May 10 at 11:53
This is my question: stackoverflow.com/questions/4896662/… . Unfortunately the simple answer that doesn't solve the problem is by using Iterables.concat(). The much longer answer gives Collection ... I wonder why this isn't more commonly supported? –  Hendy Irawan May 10 at 11:55

You may write your own utility method for this as well:

public static <E> Collection<E> makeCollection(Iterable<E> iter) {
    Collection<E> list = new ArrayList<E>();
    for (E item : iter) {
    return list;
share|improve this answer
+1 If going from Iterable to Collection is the only concern, I'd prefer this approach over importing a large 3rd party collections-library. –  aioobe Jun 20 '11 at 20:25
guava is worth improtig anyways –  Bohdan Nov 10 at 5:56

IteratorUtils from commons-collections may help (although they don't support generics in the latest stable version 3.2.1):

Collection<Type> list = IteratorUtils.toList(iterable.iterator());

Version 4.0 (which is in SNAPSHOT at this moment) supports generics and you can get rid of the @SuppressWarnings.

share|improve this answer

While at it, do not forget that all collections are finite, while Iterable has no promises whatsoever. If something is Iterable you can get an Iterator and that is it.

for (piece : sthIterable){

will be expanded to:

Iterator it = sthIterable.iterator();
while (it.hasNext()){
    piece = it.next();

it.hasNext() is not required to ever return false. Thus in the general case you cannot expect to be able to convert every Iterable to a Collection. For example you can iterate over all positive natural numbers, iterate over something with cycles in it that produces the same results over and over again, etc.

Otherwise: Atrey's answer is quite fine.

share|improve this answer
Has anyone ever actually come across an Iterable that iterates over something infinite (like the natural numbers example given in the answer), in practice / real code? I would think that such an Iterable would cause pain and woes in a lot of places... :) –  David May 6 at 12:56

From CollectionUtils:

List<T> targetCollection = new ArrayList<T>();
CollectionUtils.addAll(targetCollection, iterable.iterator())

Here are the full sources of this utility method:

public static void addAll(Collection collection, Iterator iterator) {
    while (iterator.hasNext()) {
share|improve this answer
Does it iterate through all elements directly? I.e., is Lists.newArrayList(someIterable).clear() a linear or constant time operation? –  aioobe Jun 20 '11 at 20:14
I added source code of addAll, as the name implies, it copies the iterator values one after another; it creates a copy rather than a view. –  Tomasz Nurkiewicz Jun 20 '11 at 20:18

As soon as you call contains, containsAll, equals, hashCode, remove, retainAll, size or toArray, you'd have to traverse the elements anyway.

If you're occasionally only calling methods such as isEmpty or clear I suppose you'd be better of by creating the collection lazily. You could for instance have a backing ArrayList for storing previously iterated elements.

I don't know of any such class in any library, but it should be a fairly simple exercise to write up.

share|improve this answer

I use FluentIterable.from(myIterable).toList() a lot.

share|improve this answer

Two remarks

  1. There is no need to convert Iterable to Collection to use foreach loop - Iterable may be used in such loop directly, there is no syntactical difference, so I hardly understand why the original question was asked at all.
  2. Suggested way to convert Iterable to Collection is unsafe (the same relates to CollectionUtils) - there is no guarantee that subsequent calls to the next() method return different object instances. Moreover, this concern is not pure theoretical. E.g. Iterable implementation used to pass values to a reduce method of Hadoop Reducer always returns the same value instance, just with different field values. So if you apply makeCollection from above (or CollectionUtils.addAll(Iterator)) you will end up with a collection with all identical elements.
share|improve this answer

This is not an answer to your question but I believe it is the solution to your problem. The interface org.springframework.data.repository.CrudRepository does indeed have methods that return java.lang.Iterable but you should not use this interface. Instead use sub interfaces, in your case org.springframework.data.mongodb.repository.MongoRepository. This interface has methods that return objects of type java.util.List.

share|improve this answer

In Java 8 you can do this to add all elements from an Iterable to Collection and return it:

public static <T> Collection<T> iterableToCollection(Iterable<T> iterable) {
  Collection<T> collection = new ArrayList<>();
  return collection;

Inspired by @Afreys answer.

share|improve this answer

Concise solution with Java 8 using java.util.stream:

public static <T> List<T> toList(final Iterable<T> iterable) {
    return StreamSupport.stream(iterable.spliterator(), false)
share|improve this answer

I use my custom utility to cast an existing Collection if available.


public static <T> Collection<T> toCollection(Iterable<T> iterable) {
    if (iterable instanceof Collection) {
        return (Collection<T>) iterable;
    } else {
        return Lists.newArrayList(iterable);

Ideally the above would use ImmutableList, but ImmutableCollection does not allow nulls which may provide undesirable results.


public void testToCollectionAlreadyCollection() {
    ArrayList<String> list = Lists.newArrayList(FIRST, MIDDLE, LAST);
    assertSame("no need to change, just cast", list, toCollection(list));

public void testIterableToCollection() {
    final ArrayList<String> expected = Lists.newArrayList(FIRST, null, MIDDLE, LAST);

    Collection<String> collection = toCollection(new Iterable<String>() {
        public Iterator<String> iterator() {
            return expected.iterator();
    assertNotSame("a new list must have been created", expected, collection);
    assertTrue(expected + " != " + collection, CollectionUtils.isEqualCollection(expected, collection));

I implement similar utilities for all subtypes of Collections (Set,List,etc). I'd think these would already be part of Guava, but I haven't found it.

share|improve this answer

Your Answer


