在我的应用程序中,我使用第三方库(Spring Data for MongoDB准确地说)。

这个库的方法返回Iterable<T>,而我的其余代码期望Collection<T>。

有没有什么实用的方法可以让我快速地把一个转换成另一个?为了这么简单的事情,我希望避免在代码中创建一堆foreach循环。


当前回答

尽管如此,不要忘记所有的集合都是有限的,而Iterable没有任何承诺。如果某个东西是Iterable,你可以得到一个Iterator,就是这样。

for (piece : sthIterable){
..........
}

将扩大到:

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

it.hasNext()不需要返回false。因此,在一般情况下,您不能期望能够将每个Iterable转换为一个集合。例如,你可以遍历所有正自然数,遍历带有循环的东西,反复产生相同的结果,等等。

除此之外:Atrey的回答很好。

其他回答

有点晚了,但我创建了一个非常优雅的Java 8解决方案,允许将T的Iterable转换为T的任何集合,而不需要任何库:

public static <T, C extends Collection<T>> C toCollection(Iterable<T> iterable, Supplier<C> baseSupplier) 
{
    C collection = baseSupplier.get();
    
    iterable.forEach(collection::add);
    
    return collection;
}

使用的例子:

Iterable<String> iterable = ...;
List<String> list = toCollection(iterable, ArrayList::new);

我经常使用fluentiatable .from(myIterable). tolist()。

只要你调用contains, containsAll, equals, hashCode, remove, retainAll, size或toArray,你就必须遍历元素。

如果您偶尔只调用isEmpty或clear等方法,我认为您最好是惰性地创建集合。例如,你可以有一个支持数组列表来存储先前迭代的元素。

我不知道任何一个库中有这样的类,但是编写它应该是一个相当简单的练习。

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.

你也可以编写自己的实用方法:

public static <E> Collection<E> makeCollection(Iterable<E> iter) {
    Collection<E> list = new ArrayList<E>();
    for (E item : iter) {
        list.add(item);
    }
    return list;
}