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

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

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


当前回答

如果您可以更新到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

其他回答

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

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

试试Cactoos的StickyList:

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

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

从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());
    }
}

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();
}