在我的应用程序中,我使用第三方库(Spring Data for MongoDB准确地说)。
这个库的方法返回Iterable<T>,而我的其余代码期望Collection<T>。
有没有什么实用的方法可以让我快速地把一个转换成另一个?为了这么简单的事情,我希望避免在代码中创建一堆foreach循环。
在我的应用程序中,我使用第三方库(Spring Data for MongoDB准确地说)。
这个库的方法返回Iterable<T>,而我的其余代码期望Collection<T>。
有没有什么实用的方法可以让我快速地把一个转换成另一个?为了这么简单的事情,我希望避免在代码中创建一堆foreach循环。
当前回答
有点晚了,但我创建了一个非常优雅的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;
}
从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());
}
}
如果您可以更新到Spring Data 3,那么这个问题已经解决了。有一个新的界面ListCrudRepository,它做的正是你想要的。
这是来自https://spring.io/blog/2022/02/22/announcing-listcrudrepository-friends-for-spring-data-3-0:的界面
public interface ListCrudRepository<T, ID> extends CrudRepository<T, ID> {
<S extends T> List<S> saveAll(Iterable<S> entities);
List<T> findAll();
List<T> findAllById(Iterable<ID> ids);
}
注意,在版本3中必须实现两个接口
所以在版本2中
public interface PersonRepository<Person, Long> extends
PagingAndSortingRepository<Person, Long> {}
在版本3中应改为:
public interface PersonRepository<Person, Long> extends
PagingAndSortingRepository<Person, Long>,ListCrudRepository<Person, Long> {}
其他变化见https://spring.io/blog/2022/02/22/announcing-listcrudrepository-friends-for-spring-data-3-0
来自common -collections的IteratorUtils可能会有所帮助(尽管它们在最新的稳定版本3.2.1中不支持泛型):
@SuppressWarnings("unchecked")
Collection<Type> list = IteratorUtils.toList(iterable.iterator());
4.0版本(目前在SNAPSHOT中)支持泛型,您可以去掉@SuppressWarnings。
更新:检查IterableAsList从仙人掌。
在Java 8中,你可以这样做,将Iterable中的所有元素添加到Collection中并返回:
public static <T> Collection<T> iterableToCollection(Iterable<T> iterable) {
Collection<T> collection = new ArrayList<>();
iterable.forEach(collection::add);
return collection;
}
灵感来自@Afreys的回答。