本文翻译自:Easy way to convert Iterable to Collection
In my application I use 3rd party library (Spring Data for MongoDB to be exact). 在我的应用程序中,我使用第三方库(确切地说是MongoDB的Spring Data)。
Methods of this library return Iterable<T>
, while the rest of my code expects Collection<T>
. 此库的方法返回Iterable<T>
,而我的其余代码需要Collection<T>
。
Is there any utility method somewhere that will let me quickly convert one to the other? 有什么实用方法可以让我快速将一个转换为另一个吗? I would like to avoid creating a bunch of foreach
loops in my code for such a simple thing. 我想避免在我的代码中为这么简单的事情创建一堆foreach
循环。
#1楼
参考:https://stackoom.com/question/QvHG/将Iterable转换为Collection的简便方法
#2楼
While at it, do not forget that all collections are finite, while Iterable has no promises whatsoever. 在此期间,不要忘记所有集合都是有限的,而Iterable没有任何承诺。 If something is Iterable you can get an Iterator and that is it. 如果某些东西是Iterable,你可以得到一个Iterator,就是这样。
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. it.hasNext()不需要返回false。 Thus in the general case you cannot expect to be able to convert every Iterable to a Collection. 因此,在一般情况下,您不能指望能够将每个Iterable转换为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. 否则:Atrey的答案很好。
#3楼
Two remarks 两个评论
- 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. 没有必要将Iterable转换为Collection以使用foreach循环 - Iterable可以直接在这样的循环中使用,没有语法差异,所以我很难理解为什么原来的问题被问到了。
- 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. 将Iterable转换为Collection的建议方法是不安全的(与CollectionUtils相同) - 无法保证对next()方法的后续调用返回不同的对象实例。 Moreover, this concern is not pure theoretical. 而且,这种担忧并不是纯粹的理论。 Eg Iterable implementation used to pass values to a reduce method of Hadoop Reducer always returns the same value instance, just with different field values. 例如,用于将值传递给Hadoop Reducer的reduce方法的Iterable实现总是返回相同的值实例,只是使用不同的字段值。 So if you apply makeCollection from above (or CollectionUtils.addAll(Iterator)) you will end up with a collection with all identical elements. 因此,如果您从上面应用makeCollection(或CollectionUtils.addAll(Iterator)),您将得到一个包含所有相同元素的集合。
#4楼
IteratorUtils
from commons-collections
may help (although they don't support generics in the latest stable version 3.2.1): 来自commons-collections
IteratorUtils
可能有所帮助(尽管它们不支持最新的稳定版本3.2.1中的泛型):
@SuppressWarnings("unchecked")
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
. 版本4.0(此时在SNAPSHOT中)支持泛型,你可以摆脱@SuppressWarnings
。
Update: Check IterableAsList
from Cactoos . 更新:从Cactoos检查IterableAsList
。
#5楼
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. 接口org.springframework.data.repository.CrudRepository
确实有返回java.lang.Iterable
方法,但是你不应该使用这个接口。 Instead use sub interfaces, in your case org.springframework.data.mongodb.repository.MongoRepository
. 而是使用子接口,在您的情况下是org.springframework.data.mongodb.repository.MongoRepository
。 This interface has methods that return objects of type java.util.List
. 此接口具有返回java.util.List
类型的对象的方法。
#6楼
我FluentIterable.from(myIterable).toList()
使用FluentIterable.from(myIterable).toList()
。