In meiner Anwendung verwende ich eine Bibliothek von Drittanbietern (Spring Data für MongoDB um genau zu sein).
Die Methoden dieser Bibliothek kehren zurück Iterable<T>
, während der Rest meines Codes dies erwartetCollection<T>
.
Gibt es irgendwo eine Dienstprogrammmethode, mit der ich schnell eine in die andere konvertieren kann? Ich möchte vermeiden, foreach
für eine so einfache Sache eine Reihe von Schleifen in meinem Code zu erstellen .
java
collections
Ula Krukar
quelle
quelle
Antworten:
Mit Guava können Sie unter anderem Lists.newArrayList (Iterable) oder Sets.newHashSet (Iterable) verwenden. Dadurch werden natürlich alle Elemente in den Speicher kopiert. Wenn das nicht akzeptabel ist, sollte Ihr Code, der mit diesen funktioniert,
Iterable
eher als nehmenCollection
. Guava bietet auch bequeme Methoden, um Dinge zu tun, die SieCollection
mit einemIterable
(wieIterables.isEmpty(Iterable)
oderIterables.contains(Iterable, Object)
) tun können , aber die Auswirkungen auf die Leistung sind offensichtlicher.quelle
Lists.newArrayList(Iterable).clear()
eine lineare oder konstante Zeitoperation?Collection
entweder nicht für eine Ansicht von implementiert werden könnenIterable
oder nicht effizient sind, ist es für mich nicht sehr sinnvoll, dies zu tun.Iterables.concat()
aber das gibt einIterable
, nicht einCollection
:(Iterables.concat()
. Die viel längere Antwort gibtCollection
... Ich frage mich, warum dies nicht häufiger unterstützt wird.In JDK 8+ ohne Verwendung zusätzlicher Bibliotheken:
Bearbeiten: Das obige ist für
Iterator
. Wenn Sie es zu tun habenIterable
,quelle
iterable.forEach(target::add);
Sie können auch hierfür Ihre eigene Dienstprogrammmethode schreiben:
quelle
Iterable
zuCollection
das einzige Problem ist, würde ich diesen Ansatz dem Import einer großen Sammlungsbibliothek von Drittanbietern vorziehen.Prägnante Lösung mit Java 8 mit
java.util.stream
:quelle
IteratorUtils
auscommons-collections
IteratorUtils.toList()
Verwendet den Iterator vor Java 5, um die Elemente einzeln zu einer neu erstellten Liste hinzuzufügen. Einfach und möglicherweise am schnellsten, fügt Ihrer Binärdatei jedoch 734 kB hinzu, und Sie können dies selbst tun, wenn Sie diese Methode als die beste empfinden.IteratorUtils
fromcommons-collections
kann helfen (obwohl sie in der neuesten stabilen Version 3.2.1 keine Generika unterstützen):Version 4.0 (die derzeit in SNAPSHOT enthalten ist) unterstützt Generika, und Sie können die Version entfernen
@SuppressWarnings
.Update: Überprüfen Sie
IterableAsList
von Cactoos .quelle
IterableUtils.toList(Iterable)
, was eine bequeme Methode ist undIteratorUtils
unter der Haube verwendet, aber auch null-sicher ist (im Gegensatz zuIteratorUtils.toList
).Aus CollectionUtils :
Hier sind die vollständigen Quellen dieser Dienstprogrammmethode:
quelle
Lists.newArrayList(someIterable).clear()
eine lineare oder konstante Zeitoperation?addAll
, wie der Name schon sagt, die Iteratorwerte nacheinander kopiert. Es wird eher eine Kopie als eine Ansicht erstellt.CollectionUtils
, die Erstellung der Sammlung in einer zusätzlichen Zeile zu überspringen.Vergessen Sie dabei nicht, dass alle Sammlungen endlich sind, während Iterable keinerlei Versprechen hat. Wenn etwas iterierbar ist, können Sie einen Iterator bekommen und das ist es.
wird erweitert auf:
it.hasNext () muss niemals false zurückgeben. Daher können Sie im allgemeinen Fall nicht erwarten, dass Sie jedes Iterable in eine Sammlung konvertieren können. Sie können beispielsweise alle positiven natürlichen Zahlen durchlaufen, etwas mit Zyklen durchlaufen, die immer wieder dieselben Ergebnisse liefern usw.
Ansonsten: Atreys Antwort ist ganz gut.
quelle
Ich benutze
FluentIterable.from(myIterable).toList()
viel.quelle
Dies ist keine Antwort auf Ihre Frage, aber ich glaube, es ist die Lösung für Ihr Problem. Die Schnittstelle
org.springframework.data.repository.CrudRepository
verfügt tatsächlich über Methoden, die zurückkehrenjava.lang.Iterable
, Sie sollten diese Schnittstelle jedoch nicht verwenden. Verwenden Sie in Ihrem Fall stattdessen Subschnittstellenorg.springframework.data.mongodb.repository.MongoRepository
. Diese Schnittstelle verfügt über Methoden, die Objekte vom Typ zurückgebenjava.util.List
.quelle
Ich verwende mein benutzerdefiniertes Dienstprogramm, um eine vorhandene Sammlung zu übertragen, falls verfügbar.
Main:
Im Idealfall wird ImmutableList verwendet, ImmutableCollection lässt jedoch keine Nullen zu, die zu unerwünschten Ergebnissen führen können.
Tests:
Ich implementiere ähnliche Dienstprogramme für alle Untertypen von Sammlungen (Set, List usw.). Ich würde denken, dass diese bereits Teil von Guava sind, aber ich habe sie nicht gefunden.
quelle
Sobald Sie rufen
contains
,containsAll
,equals
,hashCode
,remove
,retainAll
,size
odertoArray
würden Sie die Elemente ohnehin durchqueren müssen.Wenn Sie gelegentlich nur Methoden wie
isEmpty
oder aufrufen, istclear
es wahrscheinlich besser, wenn Sie die Sammlung träge erstellen. Sie könnten beispielsweise einen HintergrundArrayList
zum Speichern zuvor iterierter Elemente haben.Ich kenne keine solche Klasse in einer Bibliothek, aber es sollte eine ziemlich einfache Übung sein, sie aufzuschreiben.
quelle
In Java 8 können Sie dies tun, um alle Elemente von einem
Iterable
bis hinzuzufügenCollection
und zurückzugeben:Inspiriert von @Afreys Antwort.
quelle
Da RxJava ein Hammer ist und dies irgendwie wie ein Nagel aussieht, können Sie dies tun
quelle
Hier ist eine SSCCE für eine großartige Möglichkeit, dies in Java 8 zu tun
quelle
Zwei Bemerkungen
quelle
Versuchen
StickyList
von Cactoos :quelle
Ich habe keine einfache einzeilige Lösung ohne Abhängigkeiten gesehen. Ich benutze einfach
quelle
Ich bin auf eine ähnliche Situation gestoßen , als ich versucht habe, ein
List
vonProject
s abzurufen , anstatt denIterable<T> findAll()
in derCrudRepository
Schnittstelle deklarierten Standard . Also habe ich in meinerProjectRepository
Schnittstelle (die sich von erstrecktCrudRepository
) einfach diefindAll()
Methode deklariert , um aList<Project>
anstelle von zurückzugebenIterable<Project>
.Ich denke, dies ist die einfachste Lösung, ohne dass eine Konvertierungslogik oder die Verwendung externer Bibliotheken erforderlich ist.
quelle
Sie können Eclipse Collections- Fabriken verwenden:
Sie können die auch konvertieren
Iterable
zu einLazyIterable
und das Konverter - Verfahren oder eine der anderen verfügbaren APIs zur Verfügung verwenden.Alle oben genannten
Mutable
Typen erstrecken sichjava.util.Collection
.Hinweis: Ich bin ein Committer für Eclipse-Sammlungen.
quelle