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.

9voto

Ludwig Magnusson Punkte 13416

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 hat in der Tat Methoden, die Folgendes zurückgeben java.lang.Iterable aber Sie sollten diese Schnittstelle nicht verwenden. Verwenden Sie stattdessen Unterschnittstellen, in Ihrem Fall org.springframework.data.mongodb.repository.MongoRepository . Diese Schnittstelle hat Methoden, die Objekte des Typs java.util.List .

8voto

Aaron Roller Punkte 1064

Ich verwende mein benutzerdefiniertes Dienstprogramm, um eine vorhandene Sammlung zu erstellen, falls vorhanden.

Haupt:

public static <T> Collection<T> toCollection(Iterable<T> iterable) {
    if (iterable instanceof Collection) {
        return (Collection<T>) iterable;
    } else {
        return Lists.newArrayList(iterable);
    }
}

Idealerweise würde man ImmutableList verwenden, aber ImmutableCollection erlaubt keine Nullen, was zu unerwünschten Ergebnissen führen kann.

Tests:

@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));
}

Ich implementiere ähnliche Dienstprogramme für alle Untertypen von Collections (Set, List, etc). Ich würde denken, dass diese bereits Teil von Guava sind, aber ich habe sie nicht gefunden.

6voto

In Java 8 können Sie dies tun, um alle Elemente aus einem Iterable à Collection und geben Sie es zurück:

public static <T> Collection<T> iterableToCollection(Iterable<T> iterable) {
  Collection<T> collection = new ArrayList<>();
  iterable.forEach(collection::add);
  return collection;
}

Inspiriert durch @Afreys Antwort.

6voto

aioobe Punkte 397211

Sobald Sie anrufen contains , containsAll , equals , hashCode , remove , retainAll , size o toArray müssten Sie die Elemente ohnehin durchqueren.

Wenn Sie nur gelegentlich Methoden wie isEmpty o clear Ich vermute, dass es besser wäre, wenn Sie die Sammlung einfach erstellen würden. Sie könnten zum Beispiel ein Backing haben ArrayList für die Speicherung von zuvor iterierten Elementen.

Ich kenne keine solche Klasse in irgendeiner Bibliothek, aber es sollte eine recht einfache Übung sein, sie zu schreiben.

6voto

DariusL Punkte 3927

Da RxJava ein Hammer ist und dies irgendwie wie ein Nagel aussieht, können Sie

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

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