501 Stimmen

Einfacher Weg zur Konvertierung von Iterable in Collection

In meiner Anwendung verwende ich eine Bibliothek eines Drittanbieters (Spring Data für MongoDB, um genau zu sein).

Die Methoden dieser Bibliothek geben zurück Iterable<T> , während der Rest meines Codes erwartet Collection<T> .

Gibt es irgendwo eine Methode, mit der ich das eine schnell in das andere umwandeln kann? Ich würde gerne vermeiden, einen Haufen von foreach Schleifen in meinem Code für eine so einfache Sache.

46voto

Jens Schauder Punkte 70079

Wenn Sie Ihre Iterable von Spring Data haben Sie eine Reihe von zusätzlichen Alternativen.

  1. Sie können die Methode überschreiben, die die Iterable im Repository mit einer Version, die eine List , Set o Streamable . Auf diese Weise übernimmt Spring Data die Konvertierung für Sie.

  2. Sie können dies in einer Superschnittstelle Ihrer Repositories tun, damit Sie die Überschreibung nicht in allen Ihren Repository-Schnittstellen wiederholen müssen.

  3. Wenn Sie Spring Data JPA verwenden, ist dies bereits für Sie in JpaRepository

  4. Sie können die Konvertierung mit dem soeben erwähnten Streamable selbst:

    Iterable<X> iterable = repo.findAll();
    List<X> list = Streamable.of(iterable).toList();

Und da Sie erwähnen, dass Sie verärgert sind, vielleicht ein paar Hintergrundinformationen zu der Entscheidung, die Iterable ebenfalls helfen.

  1. Es wird davon ausgegangen, dass in den seltensten Fällen ein Collection In vielen Fällen dürfte es also keinen Unterschied machen.
  2. Mit Hilfe der Überschreibungsmechanismen kann man verschiedene Typen zurückgeben, was mit einem spezifischeren Rückgabetyp wie Collection . Dies würde es unmöglich machen, eine Streamable die für Fälle gedacht ist, in denen ein Speicher beschließen kann, ein Ergebnis zurückzugeben, bevor alle Elemente abgerufen wurden.
  3. Streamable wäre eigentlich ein flexibler Rückgabetyp, denn er bietet einfache Konvertierungen in List , Set , Stream und ist selbst ein Iterable . Dies würde jedoch voraussetzen, dass Sie einen spezifischen Spring Data-Typ in Ihrer Anwendung verwenden, was viele Benutzer nicht mögen würden.

Es gibt eine Abschnitt darüber in der Referenzdokumentation .

26voto

Tomasz Nurkiewicz Punkte 322861

Desde CollectionUtils :

List<T> targetCollection = new ArrayList<T>();
CollectionUtils.addAll(targetCollection, iterable.iterator())

Hier finden Sie die vollständigen Quellen für diese Methode:

public static <T> void addAll(Collection<T> collection, Iterator<T> iterator) {
    while (iterator.hasNext()) {
        collection.add(iterator.next());
    }
}

17voto

Manish Giri Punkte 3414

Ich bin auf eine ähnliche Situation gestoßen, als ich versucht habe, eine List de Project s, anstatt der Standard Iterable<T> findAll() angegeben in CrudRepository Schnittstelle. Also, in meinem ProjectRepository Schnittstelle (die sich von CrudRepository ), habe ich einfach die findAll() Methode zur Rückgabe einer 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();
}

Dies ist meiner Meinung nach die einfachste Lösung, die keine Konvertierungslogik oder die Verwendung externer Bibliotheken erfordert.

15voto

fringd Punkte 2170

Ich benutze FluentIterable.from(myIterable).toList() eine Menge.

14voto

Alexander Shopov Punkte 141

Vergessen Sie dabei nicht, dass alle Sammlungen endlich sind, während Iterable keinerlei Versprechen hat. Wenn etwas Iterable ist, kann man einen Iterator erhalten und das war's.

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

wird erweitert auf:

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

it.hasNext() muss nicht immer false zurückgeben. Daher kann man im allgemeinen Fall nicht erwarten, dass man jedes Iterable in eine Collection umwandeln kann. Man kann zum Beispiel über alle positiven natürlichen Zahlen iterieren, über etwas mit Zyklen, das immer wieder die gleichen Ergebnisse liefert, usw.

Ansonsten: Die Antwort von Atrey ist sehr gut.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X