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

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

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


当前回答

我在试图获取项目列表时遇到了类似的情况,而不是在CrudRepository接口中声明的默认Iterable<T> findAll()。因此,在我的ProjectRepository接口(从CrudRepository扩展而来)中,我简单地声明了findAll()方法来返回一个List<Project>而不是Iterable<Project>。

package com.example.projectmanagement.dao;

import com.example.projectmanagement.entities.Project;
import org.springframework.data.repository.CrudRepository;
import java.util.List;

public interface ProjectRepository extends CrudRepository<Project, Long> {

    @Override
    List<Project> findAll();
}

我认为这是最简单的解决方案,不需要转换逻辑或使用外部库。

其他回答

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

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

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

我在试图获取项目列表时遇到了类似的情况,而不是在CrudRepository接口中声明的默认Iterable<T> findAll()。因此,在我的ProjectRepository接口(从CrudRepository扩展而来)中,我简单地声明了findAll()方法来返回一个List<Project>而不是Iterable<Project>。

package com.example.projectmanagement.dao;

import com.example.projectmanagement.entities.Project;
import org.springframework.data.repository.CrudRepository;
import java.util.List;

public interface ProjectRepository extends CrudRepository<Project, Long> {

    @Override
    List<Project> findAll();
}

我认为这是最简单的解决方案,不需要转换逻辑或使用外部库。

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

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

在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的回答。