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

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

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


当前回答

试试Cactoos的StickyList:

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

其他回答

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.

这不是对你问题的回答,但我相信这是解决你问题的办法。org.springframework.data.repository.CrudRepository接口确实有返回java.lang.Iterable的方法,但是你不应该使用这个接口。而是使用子接口,在你的例子中是org.springframework.data.mongodb.repository.MongoRepository。该接口具有返回java.util.List类型对象的方法。

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

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

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

从CollectionUtils:

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

下面是这个实用方法的完整源代码:

public static <T> void addAll(Collection<T> collection, Iterator<T> iterator) {
    while (iterator.hasNext()) {
        collection.add(iterator.next());
    }
}

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

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