webentwicklung-frage-antwort-db.com.de

Wie kann ich eine Liste von Listen in eine Liste in Java 8 umwandeln?

Wenn ich einen List<List<Object>> habe, wie kann ich diesen in einen List<Object> umwandeln, der alle Objekte in derselben Iterationsreihenfolge enthält, indem ich die Funktionen von Java 8 verwende?

437
Sarah Szabo

Sie können flatMap verwenden, um die internen Listen (nach der Konvertierung in Streams) in einen einzelnen Stream zu reduzieren und das Ergebnis in einer Liste zusammenzufassen:

List<List<Object>> list = ...
List<Object> flat = 
    list.stream()
        .flatMap(List::stream)
        .collect(Collectors.toList());
791
Eran

flatmap ist besser, aber es gibt auch andere Möglichkeiten, dies zu erreichen

List<List<Object>> listOfList = ... // fill

List<Object> collect = 
      listOfList.stream()
                .collect(ArrayList::new, List::addAll, List::addAll);
42
Saravana

Die flatMap -Methode in Stream kann diese Listen zwar für Sie reduzieren, sie muss jedoch Stream Objekte für das Element und dann Stream für das Ergebnis erstellen.

Sie brauchen nicht alle diese Stream Objekte. Hier ist der einfache, übersichtliche Code zum Ausführen der Aufgabe.

_// listOfLists is a List<List<Object>>.
List<Object> result = new ArrayList<>();
listOfLists.forEach(result::addAll);
_

Da ListIterable ist, ruft dieser Code die Methode forEach (Java 8-Funktion) auf, die von Iterable geerbt wird.

Führt die angegebene Aktion für jedes Element von Iterable aus, bis alle Elemente verarbeitet wurden oder die Aktion eine Ausnahme auslöst. Aktionen werden in der Reihenfolge der Iteration ausgeführt, wenn diese Reihenfolge angegeben ist.

Und das List eines Iterator gibt Elemente in sequenzieller Reihenfolge zurück.

Für Consumer übergibt dieser Code eine Methodenreferenz (Java 8-Feature) an die Methode vor Java 8 List.addAll , um die inneren Listenelemente nacheinander hinzuzufügen.

Hängt alle Elemente in der angegebenen Sammlung an das Ende dieser Liste an, in der Reihenfolge, in der sie vom Iterator der angegebenen Sammlung zurückgegeben werden (optionale Operation).

20
rgettman

Sie können das Muster flatCollect() aus Eclipse Collections verwenden.

MutableList<List<Object>> list = Lists.mutable.empty();
MutableList<Object> flat = list.flatCollect(each -> each);

Wenn Sie die Liste von List nicht ändern können:

List<List<Object>> list = new ArrayList<>();
List<Object> flat = ListAdapter.adapt(list).flatCollect(each -> each);

Hinweis: Ich arbeite an Eclipse-Sammlungen mit.

12

So wie @Saravana es erwähnt hat:

flatmap ist besser, aber es gibt auch andere möglichkeiten, dies zu erreichen

 listStream.reduce(new ArrayList<>(), (l1, l2) -> {
        l1.addAll(l2);
        return l1;
 });

Zusammenfassend lässt sich sagen, dass es mehrere Möglichkeiten gibt, dasselbe zu erreichen:

private <T> List<T> mergeOne(Stream<List<T>> listStream) {
    return listStream.flatMap(List::stream).collect(toList());
}

private <T> List<T> mergeTwo(Stream<List<T>> listStream) {
    List<T> result = new ArrayList<>();
    listStream.forEach(result::addAll);
    return result;
}

private <T> List<T> mergeThree(Stream<List<T>> listStream) {
    return listStream.reduce(new ArrayList<>(), (l1, l2) -> {
        l1.addAll(l2);
        return l1;
    });
}

private <T> List<T> mergeFour(Stream<List<T>> listStream) {
    return listStream.reduce((l1, l2) -> {
        List<T> l = new ArrayList<>(l1);
        l.addAll(l2);
        return l;
    }).orElse(new ArrayList<>());
}

private <T> List<T> mergeFive(Stream<List<T>> listStream) {
    return listStream.collect(ArrayList::new, List::addAll, List::addAll);
}
8
Hearen

Ich möchte nur ein weiteres Szenario wie List<Documents> erläutern. Diese Liste enthält einige weitere Listen anderer Dokumente wie List<Excel>, List<Word>, List<PowerPoint>. So ist die Struktur

class A {
  List<Documents> documentList;
}

class Documents {
  List<Excel> excels;
  List<Word> words;
  List<PowerPoint> ppt;
}

Wenn Sie Excel nur aus Dokumenten iterieren möchten, gehen Sie wie folgt vor.

Also wäre der Code

 List<Documents> documentList = new A().getDocumentList();

 //check documentList as not null

 Optional<Excel> excelOptional = documentList.stream()
                         .map(doc -> doc.getExcel())
                         .flatMap(List::stream).findFirst();
 if(excelOptional.isPresent()){
   Excel exl = optionalExcel.get();
   // now get the value what you want.
 }

Ich hoffe, dies kann jemandes Problem beim Codieren lösen ...

5
Kushwaha

Methode zum Konvertieren von "Liste von Listen in Liste konvertieren": ListOfLists.stream (). FlatMap (List :: stream) .collect (Collectors.toList ()); Beispiel 1 :

    public class ConvertListOfListsToList {
        public static void main(String[] args) {
            List<String> StringList = Arrays.asList("Protijayi", "Gini", "Gina");
            System.out.println(StringList);
            List<List<String>> ListOfLists = new ArrayList<>();
            ListOfLists.add(StringList);

            System.out.println("ListOfLists => " + ListOfLists);

            // Now let's do this in Java 8 using FlatMap
            List<String> flatMapList = ListOfLists.stream().flatMap(List::stream).collect(Collectors.toList());

            System.out.println("FlatList =>  " + flatMapList);
/*
ListOfLists => [[Protijayi, Gini, Gina]]
FlatList =>  [Protijayi, Gini, Gina]
*/
        }

    }
1
Soudipta Dutta

Eine Erweiterung von Erans Antwort, die die beste Antwort war. Wenn Sie eine Reihe von Listenebenen haben, können Sie diese weiterhin mit einem Flatmapping versehen.

Dies bietet auch eine praktische Möglichkeit zum Filtern, wenn Sie die Ebenen bei Bedarf durchgehen.

Also zum Beispiel:

List<List<List<List<List<List<Object>>>>>> multiLayeredList = ...

List<Object> objectList = multiLayeredList
    .stream()
    .flatmap(someList1 -> someList1
        .stream()
        .filter(...Optional...))
    .flatmap(someList2 -> someList2
        .stream()
        .filter(...Optional...))
    .flatmap(someList3 -> someList3
        .stream()
        .filter(...Optional...))
    ...
    .collect(Collectors.toList())

Dies ist in SQL vergleichbar mit SELECT-Anweisungen in SELECT-Anweisungen.

0
cody.tv.weber

Wir können Flatmap für diese verwenden, bitte beziehen Sie sich auf den folgenden Code:

 List<Integer> i1= Arrays.asList(1, 2, 3, 4);
 List<Integer> i2= Arrays.asList(5, 6, 7, 8);

 List<List<Integer>> ii= Arrays.asList(i1, i2);
 System.out.println("List<List<Integer>>"+ii);
 List<Integer> flat=ii.stream().flatMap(l-> l.stream()).collect(Collectors.toList());
 System.out.println("Flattened to List<Integer>"+flat);
0
Pratik Pawar