491 Stimmen

Abrufen einer Liste aus einem java.util.stream.Stream in Java 8

Ich habe mit Java 8 Lambdas herumgespielt, um Kollektionen einfach zu filtern. Aber ich habe keinen prägnanten Weg gefunden, um das Ergebnis in Form einer neuen Liste im selben Statement abzurufen. Hier ist mein bisher prägnantester Ansatz:

List sourceLongList = Arrays.asList(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
List targetLongList = new ArrayList<>();
sourceLongList.stream().filter(l -> l > 100).forEach(targetLongList::add);

Beispiele im Netz haben meine Frage nicht beantwortet, weil sie ohne Erzeugung einer neuen Ergebnisliste enden. Es muss einen prägnanteren Weg geben. Ich hätte erwartet, dass die Stream-Klasse Methoden wie toList(), toSet(), ... hat.

Gibt es einen Weg, wie die Variable targetLongList direkt in der dritten Zeile zugewiesen werden kann?

5voto

Nikhil Nanivadekar Punkte 1132

Wenn Sie ein Array von Primitiven haben, können Sie die in Eclipse Collections verfügbaren Primitivsammlungen verwenden.

LongList sourceLongList = LongLists.mutable.of(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
LongList targetLongList = sourceLongList.select(l -> l > 100);

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

List sourceLongList = Arrays.asList(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
List targetLongList = 
    ListAdapter.adapt(sourceLongList).select(l -> l > 100, new ArrayList<>());

Wenn Sie LongStream verwenden möchten:

long[] sourceLongs = new long[]{1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L};
LongList targetList = 
    LongStream.of(sourceLongs)
    .filter(l -> l > 100)
    .collect(LongArrayList::new, LongArrayList::add, LongArrayList::addAll);

Hinweis: Ich bin ein Beitragender zu Eclipse Collections.

5voto

msayag Punkte 7878

Eine etwas effizientere Methode (um das Erstellen der Quellliste und das automatische Entpacken durch den Filter zu vermeiden):

List targetLongList = LongStream.of(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L)
    .filter(l -> l > 100)
    .boxed()
    .collect(Collectors.toList());

1voto

John McClean Punkte 5017

Wenn es Ihnen nichts ausmacht, 3rd-Party-Bibliotheken zu verwenden, bietet AOL's cyclops-react lib (Offenlegung: Ich bin ein Mitwirkender) Erweiterungen für alle JDK Collection-Typen, einschließlich List. Das ListX-Interface erweitert java.util.List und fügt eine große Anzahl nützlicher Operatoren hinzu, einschließlich filter.

Sie können einfach schreiben-

ListX sourceLongList = ListX.of(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
ListX targetLongList = sourceLongList.filter(l -> l > 100);

ListX kann auch aus einer vorhandenen Liste erstellt werden (über ListX.fromIterable)

1voto

Vaneet Kataria Punkte 497

Es gibt eine weitere Variante der collect-Methode, die von der LongStream-Klasse bereitgestellt wird, und ebenfalls von den Klassen IntStream und DoubleStream.

 R collect(Supplier supplier,
              ObjLongConsumer accumulator,
              BiConsumer combiner)

Führt eine mutierbare Reduktionsoperation auf den Elementen dieses Streams aus. Eine mutierbare Reduktion ist eine, bei der der reduzierte Wert ein mutierbarer Ergebniscontainer ist, wie z.B. ein ArrayList, und Elemente werden eingefügt, indem der Zustand des Ergebnisses aktualisiert wird, anstatt das Ergebnis zu ersetzen. Dies ergibt ein Ergebnis, das äquivalent zu ist:

R result = supplier.get();
  for (long element : this stream)
       accumulator.accept(result, element);
  return result;

Wie bei reduce(long, LongBinaryOperator) können auch Sammelvorgänge parallelisiert werden, ohne zusätzliche Synchronisation zu erfordern. Dies ist eine Terminaloperation.

Und die Antwort auf deine Frage mit dieser collect-Methode lautet wie folgt :

    LongStream.of(1L, 2L, 3L, 3L).filter(i -> i > 2)
    .collect(ArrayList::new, (list, value) -> list.add(value)
    , (list1, list2) -> list1.addAll(list2));

Hier ist die Methodenreferenzvariante, die ziemlich clever, aber etwas knifflig zu verstehen ist:

     LongStream.of(1L, 2L, 3L, 3L).filter(i -> i > 2)
    .collect(ArrayList::new, List::add , List::addAll);

Als Nächstes folgt die HashSet-Variante :

     LongStream.of(1L, 2L, 3L, 3).filter(i -> i > 2)
     .collect(HashSet::new, HashSet::add, HashSet::addAll);

Außerdem ist die LinkedList-Variante wie folgt :

     LongStream.of(1L, 2L, 3L, 3L)
     .filter(i -> i > 2)
     .collect(LinkedList::new, LinkedList::add, LinkedList::addAll);

1voto

Saikat Punkte 10782

Um in einer veränderbaren Liste zu sammeln:

targetList = sourceList.stream()
                       .filter(i -> i > 100) //Filter anwenden
                       .collect(Collectors.toList());

Um in einer unveränderbaren Liste zu sammeln:

targetList = sourceList.stream()
                       .filter(i -> i > 100) //Filter anwenden
                       .collect(Collectors.toUnmodifiableList());

Erklärung von collect aus dem JavaDoc:

Führt eine veränderbare Reduktionsoperation auf den Elementen dieses Streams unter Verwendung eines Collectors durch. Ein Collector kapselt die Funktionen, die als Argumente für collect(Supplier, BiConsumer, BiConsumer) verwendet werden, was die Wiederverwendung von Sammlungsstrategien und die Komposition von Sammeloperationen ermöglicht, wie beispielsweise das Gruppieren oder Partitionieren auf mehreren Ebenen. Wenn der Stream parallel ist und der Collector nebenläufig ist und entweder der Stream ungeordnet ist oder der Collector ungeordnet ist, wird eine nebenläufige Reduktion durchgeführt (siehe Collector für Details zur nebenläufigen Reduktion).

Dies ist eine Abschlussoperation.

Bei Ausführung in Parallelität können mehrere Zwischenergebnisse instanziiert, bevölkert und fusioniert werden, um die Isolierung von veränderbaren Datenstrukturen aufrechtzuerhalten. Daher, selbst bei Ausführung in Parallelität mit nicht thread-sicheren Datenstrukturen (wie ArrayList), ist keine zusätzliche Synchronisation für eine parallele Reduktion erforderlich.

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