私のアプリケーションでは、サードパーティのライブラリを使用しています(正確には、MongoDBの春のデータ)。
このライブラリのメソッドは戻りますがIterable<T>、残りのコードは期待していCollection<T>ます。
すぐに一方をもう一方に変換できるユーティリティメソッドはありますか?foreachこのような単純なことのために、コード内に多数のループを作成することは避けたいと思います。
私のアプリケーションでは、サードパーティのライブラリを使用しています(正確には、MongoDBの春のデータ)。
このライブラリのメソッドは戻りますがIterable<T>、残りのコードは期待していCollection<T>ます。
すぐに一方をもう一方に変換できるユーティリティメソッドはありますか?foreachこのような単純なことのために、コード内に多数のループを作成することは避けたいと思います。
回答:
グァバを使用できLists.newArrayList(反復処理可能)またはSets.newHashSet(反復処理可能)を他の同様の方法の中で、。もちろん、これはすべての要素をメモリにコピーします。それが受け入れられない場合は、これらのコードで動作するコードは、Iterableではなくを使用する必要がありCollectionます。グアバはまた、上のあなたができることをやってするのに便利な方法を提供するためにたまたまCollection使用してIterable(例えばIterables.isEmpty(Iterable)またはIterables.contains(Iterable, Object))が、パフォーマンスへの影響はより明白です。
Lists.newArrayList(Iterable).clear()線状または一定時間操作が?
                    Collectionはのビューに実装できないかIterable、効率的ではないため、それを行うことはあまり意味がありません。
                    Iterables.concat()がIterable、それはCollection:( ではなく)を与えます
                    Iterables.concat()です。はるかに長い答えが得られCollectionます...なぜこれがより一般的にサポートされていないのでしょうか?
                    このための独自のユーティリティメソッドを作成することもできます。
public static <E> Collection<E> makeCollection(Iterable<E> iter) {
    Collection<E> list = new ArrayList<E>();
    for (E item : iter) {
        list.add(item);
    }
    return list;
}
              Iterableへの移行Collectionが唯一の懸念事項である場合、私は、大規模なサードパーティのコレクションライブラリをインポートするよりも、このアプローチの方を好みます。
                    を使用したJava 8による簡潔なソリューションjava.util.stream:
public static <T> List<T> toList(final Iterable<T> iterable) {
    return StreamSupport.stream(iterable.spliterator(), false)
                        .collect(Collectors.toList());
}
              IteratorUtils、commons-collections
                    IteratorUtils.toList()Java 5より前の方法でイテレータを使用して、新しく作成したリストに要素を1つずつ追加します。シンプルでおそらく最速ですが、バイナリに734 kBが追加されます。この方法が最善であるとわかった場合は、自分でこれを行うことができます。
                    IteratorUtilsfrom commons-collectionsが役立つ場合があります(ただし、最新の安定したバージョン3.2.1ではジェネリックをサポートしていません)。
@SuppressWarnings("unchecked")
Collection<Type> list = IteratorUtils.toList(iterable.iterator());
バージョン4.0(現時点ではSNAPSHOTにあります)はジェネリックをサポートしており、を取り除くことができます@SuppressWarnings。
更新:CactoosIterableAsListから確認してください。
IterableUtils.toList(Iterable)は、便利なメソッドでありIteratorUtils、内部で使用するもありますが、(とは異なりIteratorUtils.toList)nullセーフでもあります。
                    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());
    }
}
              Lists.newArrayList(someIterable).clear()線状または一定時間操作が?
                    addAll名前が示すように、のソースコードを追加しました。イテレータの値を次々にコピーします。ビューではなくコピーを作成します。
                    CollectionUtils追加の行でコレクションの作成をスキップする方法がないのは残念です。
                    その間、すべてのコレクションが有限であることを忘れないでください。一方、Iterableにはまったく約束がありません。何かがIterableであれば、イテレーターを取得できます。
for (piece : sthIterable){
..........
}
次のように展開されます:
Iterator it = sthIterable.iterator();
while (it.hasNext()){
    piece = it.next();
..........
}
it.hasNext()がfalseを返す必要はありません。したがって、一般的なケースでは、すべてのIterableをコレクションに変換できるとは期待できません。たとえば、すべての正の自然数を反復処理したり、同じ結果を繰り返し生成するサイクルがあるものを反復処理したりできます。
それ以外の場合:Atreyの答えはかなり問題ありません。
これはあなたの質問に対する答えではありませんが、私はそれがあなたの問題の解決策であると信じています。このインターフェースにorg.springframework.data.repository.CrudRepositoryは確かに戻るメソッドjava.lang.Iterableがありますが、このインターフェースは使用しないでください。代わりに、サブインターフェースを使用してくださいorg.springframework.data.mongodb.repository.MongoRepository。このインターフェイスには、タイプのオブジェクトを返すメソッドがありますjava.util.List。
カスタムユーティリティを使用して、可能であれば既存のコレクションをキャストします。
メイン:
public static <T> Collection<T> toCollection(Iterable<T> iterable) {
    if (iterable instanceof Collection) {
        return (Collection<T>) iterable;
    } else {
        return Lists.newArrayList(iterable);
    }
}
上記ではImmutableListを使用するのが理想的ですが、ImmutableCollectionではnullが許可されないため、望ましくない結果が生じる可能性があります。
テスト:
@Test
public void testToCollectionAlreadyCollection() {
    ArrayList<String> list = Lists.newArrayList(FIRST, MIDDLE, LAST);
    assertSame("no need to change, just cast", list, toCollection(list));
}
@Test
public void testIterableToCollection() {
    final ArrayList<String> expected = Lists.newArrayList(FIRST, null, MIDDLE, LAST);
    Collection<String> collection = toCollection(new Iterable<String>() {
        @Override
        public Iterator<String> iterator() {
            return expected.iterator();
        }
    });
    assertNotSame("a new list must have been created", expected, collection);
    assertTrue(expected + " != " + collection, CollectionUtils.isEqualCollection(expected, collection));
}
コレクションのすべてのサブタイプ(Set、Listなど)に同様のユーティリティを実装します。これらはすでにグアバの一部であると思いますが、私はそれを見つけていません。
すぐに呼び出すようcontains、containsAll、equals、hashCode、remove、retainAll、sizeまたはtoArray、あなたはとにかく要素をトラバースする必要があると思います。
isEmptyまたはのようなメソッドを時々呼び出すだけの場合はclear、コレクションを遅延して作成した方がいいと思います。あなたは例えばバッキングを持つことができますArrayList以前に反復された要素を格納するためを。
私はどのライブラリでもそのようなクラスを知りませんが、書くのはかなり簡単な練習になるはずです。
Java 8では、これを実行してtoからすべての要素を追加IterableしCollection、それを返すことができます。
public static <T> Collection<T> iterableToCollection(Iterable<T> iterable) {
  Collection<T> collection = new ArrayList<>();
  iterable.forEach(collection::add);
  return collection;
}
@Afreysの回答に触発されました。
RxJavaはハンマーであり、これはちょっと爪のように見えるので、
Observable.from(iterable).toList().toBlocking().single();
              これは、Java 8でこれを行うための優れた方法のSSCCEです
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class IterableToCollection {
    public interface CollectionFactory <T, U extends Collection<T>> {
        U createCollection();
    }
    public static <T, U extends Collection<T>> U collect(Iterable<T> iterable, CollectionFactory<T, U> factory) {
        U collection = factory.createCollection();
        iterable.forEach(collection::add);
        return collection;
    }
    public static void main(String[] args) {
        Iterable<Integer> iterable = IntStream.range(0, 5).boxed().collect(Collectors.toList());
        ArrayList<Integer> arrayList = collect(iterable, ArrayList::new);
        HashSet<Integer> hashSet = collect(iterable, HashSet::new);
        LinkedList<Integer> linkedList = collect(iterable, LinkedList::new);
    }
}
              インターフェイスで宣言されているデフォルトではなくList、Projectのを取得しようとしたときに、同様の状況に遭遇しました。したがって、(から拡張された)私のインターフェースでは、の代わりにを返すようにメソッドを宣言しました。Iterable<T> findAll()CrudRepositoryProjectRepositoryCrudRepositoryfindAll()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();
}
これは、変換ロジックや外部ライブラリの使用を必要としない、最も単純なソリューションだと思います。
二つの発言
Eclipseコレクションファクトリを使用できます。
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();
上記のMutableタイプはすべて拡張されjava.util.Collectionます。
注:私はEclipseコレクションのコミッターです。