在我的应用程序中,我使用第三方库(Spring Data for MongoDB准确地说)。
这个库的方法返回Iterable<T>,而我的其余代码期望Collection<T>。
有没有什么实用的方法可以让我快速地把一个转换成另一个?为了这么简单的事情,我希望避免在代码中创建一堆foreach循环。
在我的应用程序中,我使用第三方库(Spring Data for MongoDB准确地说)。
这个库的方法返回Iterable<T>,而我的其余代码期望Collection<T>。
有没有什么实用的方法可以让我快速地把一个转换成另一个?为了这么简单的事情,我希望避免在代码中创建一堆foreach循环。
当前回答
你也可以编写自己的实用方法:
public static <E> Collection<E> makeCollection(Iterable<E> iter) {
Collection<E> list = new ArrayList<E>();
for (E item : iter) {
list.add(item);
}
return list;
}
其他回答
只要你调用contains, containsAll, equals, hashCode, remove, retainAll, size或toArray,你就必须遍历元素。
如果您偶尔只调用isEmpty或clear等方法,我认为您最好是惰性地创建集合。例如,你可以有一个支持数组列表来存储先前迭代的元素。
我不知道任何一个库中有这样的类,但是编写它应该是一个相当简单的练习。
两个评论
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. 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.
Java 8使用Java .util.stream的简洁解决方案:
public static <T> List<T> toList(final Iterable<T> iterable) {
return StreamSupport.stream(iterable.spliterator(), false)
.collect(Collectors.toList());
}
从Java 16开始,你可以使用Stream.toList():
public static <T> List<T> toList(final Iterable<T> iterable) {
return StreamSupport.stream(iterable.spliterator(), false)
.toList();
}
这不是对你问题的回答,但我相信这是解决你问题的办法。org.springframework.data.repository.CrudRepository接口确实有返回java.lang.Iterable的方法,但是你不应该使用这个接口。而是使用子接口,在你的例子中是org.springframework.data.mongodb.repository.MongoRepository。该接口具有返回java.util.List类型对象的方法。
您可以使用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的提交者。