Java: .map().flatMap).map().collect()

Gast #6252470
Was ergibt am Ende das untere Konstrukt?
1
.map().flatMap).map()collect()

Code Beispiel:
1
SortedSet<String> signalNames = new TreeSet<>();
2

3
signalNames.addAll
4
(varList.stream().map(variant::getSignals)
5
                 .flatMap(SortedSet<Signal>::stream)
6
                 .map(Signal::getSignalName)
7
                 .collect(Collectors.toList()));

In den einzelnen Typen sind ja Methodenaufrufe da. Gemeint ist z.B. dass 
variant::getSignals ein Methodenaufruf ist.

Was ich nicht verstehe, welchen Typ vom Parameter kriegt jetzt die 
Methode addAll?
#6252523
Vili schrieb:
> Was ergibt am Ende das untere Konstrukt?
>
>
1
.map().flatMap).map()collect()
Dieser Code zeigt wieder mal, warum ich Java verabscheue.
In jedem Java-Code, in den ich reingeschaut habe, waren
solche Konstrukte zu finden.

> Was ich nicht verstehe, welchen Typ vom Parameter kriegt jetzt die
> Methode addAll?
Ich nehme an, collect() liefert Liste (oder einen
adäquaten Container) zurück.

merciless
Gast #6254875
Dirk K. schrieb:
> Dieser Code zeigt wieder mal, warum ich Java verabscheue.
> In jedem Java-Code, in den ich reingeschaut habe, waren
> solche Konstrukte zu finden.

Ich finde das prima zu lesen. Vermutlich besser, als die 3 mal so lange 
ausformulierte Variante mit Schleife und temporären Hilfscollections. 
Wenn man das vernünftig formatiert, entspricht jede Zeile in so einer 
Kette einer Operation auf der Collection, die wieder eine irgendwie 
geartete Collection zurückgibt. Kommentare fressen natürlich kein Brot 
und wären nett, um die Intention der jeweiligen Einzeloperation nochmal 
zu zeigen.

Ich habe das letzte Mal mit Java entwickelt, als es das Kram noch nicht 
gab. Trotzdem denke ich, auf einen Blick ein halbwegs gutes Verständnis 
zu haben, was dort passieren soll...
#6254941
Hi zusammen

Wie Dirk bereits gesagt hat entspricht jede Codezeile einer Operation:

1) Für jedes Element (var) in varList tue....
.stream()

2) Rufe die Liste der Signale von var ab
.map(variant::getSignals)

3) Für jedes Element (signal) in der Signalliste tue...
.flatMap(SortedSet<Signal>::stream)

4) Rufe des Signalnamen von Signal ab
.map(Signal::getSignalName)

5) Sammle alles in einer Liste (vom Typ List<String>) und gib diese 
zurück
.collect(Collectors.toList()))

Hier mal ein Beispiel wie das ganze ausgeschrieben aussehen würde:
1
SortedSet<String> signalNames = new TreeSet<>();
2
List<String> temp = new ArrayList<>();
3

4
for (variant var : varList)
5
{
6
   for (Signal signal : var.getSignals())
7
   {
8
      temp.add(signal.getSignalName());
9
   }
10
}
11

12
signalNames.addAll(temp);

Gruß
Christian
Gast #6255335
Christian F. schrieb:
> Wie Dirk bereits gesagt hat entspricht jede Codezeile einer Operation:

Meine Programmierkenntnisse beschränken sich auf Python und VBA, aber 
ich war davon ausgegangen, daß das ganze von rechts nach links 
abgearbeitet wird, also collect liefert was an map, was wiederum an 
flatmap übergeben wird usw. Auf das von Christian F. geschilderte 
Verhalten wäre ich nie gekommen...
Gast #6255593
Markus schrieb:
> Christian F. schrieb:
>> Wie Dirk bereits gesagt hat entspricht jede Codezeile einer Operation:
>
> Meine Programmierkenntnisse beschränken sich auf Python und VBA, aber
> ich war davon ausgegangen, daß das ganze von rechts nach links
> abgearbeitet wird, also collect liefert was an map, was wiederum an
> flatmap übergeben wird usw. Auf das von Christian F. geschilderte
> Verhalten wäre ich nie gekommen...

Das Verhalten ist genau so auch in Python und VBA
Gast #6259249
Obwohl man das mit addAll in dem Fall nicht macht, da collect direkt ein 
TreeSet zurückgeben kann.

Also eher:

SortedSet<String> signalNames = varList.stream()
    .map(variant::getSignals)
    .flatMap(Collections::stream)
    .map(Signal::getSignalName)
    .collect(Collectors.toCollection(TreeSet::new)));
Gast #6259268
Achso, du solltest dir auch überlegen, ob es wirklich eine immer 
sortiere Menge sein muss. TreeSet ist halt langsam beim hinzufügen, 
löschen von Elementen.

Wenn du die Liste nur 1x erzeugst und dann nicht mehr änderst wäre 
folgendes performanter.

List<String> signalNames = varList.stream()
    .map(variant::getSignals)
    .flatMap(Collections::stream)
    .map(Signal::getSignalName)
    .distinct() // Filtert doppelte Einträge aus
    .sorted() // Sortiert anschließend nach der natürlichen Ordnung
    .collect(Collectors.toList()));

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.