[java] Iterable을 Collection으로 변환하는 쉬운 방법

내 응용 프로그램에서 타사 라이브러리 (MongoDB의 스프링 데이터가 정확함)를 사용합니다.

이 라이브러리의 메소드는 반환 Iterable<T>하지만 나머지 코드는 예상 Collection<T>합니다.

어딘가에 빠르게 변환 할 수있는 유틸리티 방법이 있습니까? foreach그런 간단한 일을 위해 코드에 많은 루프를 만드는 것을 피하고 싶습니다 .



답변

함께 구아바 당신이 사용할 수있는 Lists.newArrayList (의 Iterable) 또는 Sets.newHashSet (의 Iterable를) 다른 유사한 방법들. 이것은 물론 모든 요소를 ​​메모리에 복사합니다. 그것이 받아 들일 수 없다면, 이것들과 작동하는 코드는 Iterable오히려 사용해야한다고 생각합니다 Collection. 구아바는 또한 당신이 할 수있는 일을하는 편리한 방법을 제공하는 일이 Collection를 사용하여 Iterable(예 : Iterables.isEmpty(Iterable)또는 Iterables.contains(Iterable, Object)),하지만 성능에 영향이 더 분명하다.


답변

추가 라이브러리를 사용하지 않고 JDK 8 이상에서 :

Iterator<T> source = ...;
List<T> target = new ArrayList<>();
source.forEachRemaining(target::add);

편집 : 위의 내용은입니다 Iterator. 당신이 다루고있는 경우 Iterable,

iterable.forEach(target::add);


답변

이것에 대한 고유 한 유틸리티 메소드를 작성할 수도 있습니다.

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을 사용한 간결한 솔루션 java.util.stream:

public static <T> List<T> toList(final Iterable<T> iterable) {
    return StreamSupport.stream(iterable.spliterator(), false)
                        .collect(Collectors.toList());
}


답변

IteratorUtilsfrom commons-collectionsmay help (최신 안정 버전 3.2.1에서는 제네릭을 지원하지 않지만) :

@SuppressWarnings("unchecked")
Collection<Type> list = IteratorUtils.toList(iterable.iterator());

버전 4.0 (현재 SNAPSHOT에 있음)은 제네릭을 지원하며 @SuppressWarnings .

업데이트 : CactoosIterableAsList 에서 확인하십시오 .


답변

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


답변

Iterable은 약속이 없지만 모든 컬렉션은 유한하다는 것을 잊지 마십시오. Iterable이 있으면 Iterator를 얻을 수 있습니다.

for (piece : sthIterable){
..........
}

다음으로 확장됩니다 :

Iterator it = sthIterable.iterator();
while (it.hasNext()){
    piece = it.next();
..........
}

it.hasNext ()는 false를 반환하지 않아도됩니다. 따라서 일반적인 경우 모든 Iterable을 Collection으로 변환 할 수는 없습니다. 예를 들어, 모든 양수의 자연수를 반복하고,주기가 같은 것을 반복하여 동일한 결과를 반복해서 반복 할 수 있습니다.

그렇지 않으면 : Atrey의 대답은 꽤 좋습니다.