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

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

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


当前回答

试试Cactoos的StickyList:

List<String> list = new StickyList<>(iterable);

其他回答

来自common -collections的IteratorUtils可能会有所帮助(尽管它们在最新的稳定版本3.2.1中不支持泛型):

@SuppressWarnings("unchecked")
Collection<Type> list = IteratorUtils.toList(iterable.iterator());

4.0版本(目前在SNAPSHOT中)支持泛型,您可以去掉@SuppressWarnings。

更新:检查IterableAsList从仙人掌。

您可以使用Eclipse Collections工厂:

Iterable<String> iterable = Arrays.asList("1", "2", "3");

MutableList<String> list = Lists.mutable.withAll(iterable);
MutableSet<String> set = Sets.mutable.withAll(iterable);
MutableSortedSet<String> sortedSet = SortedSets.mutable.withAll(iterable);
MutableBag<String> bag = Bags.mutable.withAll(iterable);
MutableSortedBag<String> sortedBag = SortedBags.mutable.withAll(iterable);

您还可以将Iterable转换为LazyIterable,并使用转换器方法或任何其他可用的api。

Iterable<String> iterable = Arrays.asList("1", "2", "3");
LazyIterable<String> lazy = LazyIterate.adapt(iterable);

MutableList<String> list = lazy.toList();
MutableSet<String> set = lazy.toSet();
MutableSortedSet<String> sortedSet = lazy.toSortedSet();
MutableBag<String> bag = lazy.toBag();
MutableSortedBag<String> sortedBag = lazy.toSortedBag();

以上所有可变类型都扩展了java.util.Collection。

注意:我是Eclipse Collections的提交者。

因为RxJava是一个锤子,而这个看起来像钉子,你可以这样做

Observable.from(iterable).toList().toBlocking().single();

有点晚了,但我创建了一个非常优雅的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);

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

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