2016-08-05 28 views
0

bearbeiten filtern:Java Streams - Wie basierend auf Funktionsausgang richtig

Grundsätzlich möchte ich alle Einträge filtern, ob entry.getObject() ist ein String, der Wert „Wert“ enthält.


So habe ich einen Block von Code, der etwa wie folgt aussieht:

list.stream() 
    .filter((entry) -> entry.getObject() != null) 
    .filter((entry) -> entry.getObject() instanceof String) 
    .filter((entry) -> ((String)entry.getObject()).toLowerCase().contains(value)) 
    .collect(Collectors.toList()); 

Das Hauptproblem ist, dass ich nicht herausfinden kann, wie dies zu strukturieren den Wert von entry.getObject anhalten(), und ich kann nicht herausfinden, wie man die Ausgabe von entry.getObject() manipuliert, ohne den Eintrag aus den Augen zu verlieren, der den Wert ergeben hat. Frühere Versuche sah mehr wie folgt aus:

list.stream() 
    .map((entry) -> entry.getObject()) 
    .filter((object) -> entry instanceof String) 
    .map((object) -> (String)entry) 
    .filter((str) -> str.toLowerCase().contains(value)) 
    /* ... */ 

Aber dann konnte ich keine Möglichkeit, herauszufinden, um es auf den Eintrag in der Liste zu beziehen, die ich mit begann.

+0

Was entspricht die Klasse dem Eintrag? –

+0

Wenn ich Ihre Bedürfnisse richtig verstehe, möchten Sie Ihre Änderung in der Zeichenfolge im entsprechenden Eintrag widerspiegeln? –

+0

Nein, im Grunde möchte ich basierend auf einer Eigenschaft einer Zeichenfolge filtern, die ich von "Eintrag" erhalten, aber um diese Eigenschaft zu bestimmen, muss ich auch die Zeichenfolge in verschiedenen Phasen zuordnen und filtern. – user1125238

Antwort

-1

Sie etwas tun könnte, wie

list.stream() 
    .map((e) -> new Entry(e, e.getObject())) 
    .filter((p) -> p.getValue() instanceof String) 
    //... 
    .map((p) -> p.getKey()) 
    .collect(Collectors.toList()); 

Mit Map.Entry oder swing.Pair (oder Ihre eigenen Tupel artiger Struktur rollen)

0

Eine mögliche Lösung könnte so aussehen:

list.stream() 
    .filter((entry) -> Arrays.stream(new Entry[] {entry}) 

     // Map from entry to entry.getObject() 
     .map((entry) -> entry.getObject()) 

     // Remove any objects that aren't strings 

     .filter((object) -> entry instanceof String) 

     // Map the object to a string 
     .map((object) -> (String)entry) 

     // Remove any strings that don't contain the value 
     .filter((str) -> str.toLowerCase().contains(value)) 

     // If there is a product remaining, then entry is what I want 
     .count() > 0) 

    .collect(Collectors.toList()); 

Auf diese Weise können wir entry.getObject() ohne mehrere Aufrufe trennen und analysieren, um den Wert bei jedem Schritt zurückzuerhalten.

+1

Verwenden Sie Arrays.stream(), um ein Array zu streamen, ohne eine Zwischenliste zu erstellen – Pausbrak

+0

@Pausbrak Wird es tun! Bearbeitet in. – user1125238

+0

Sie benötigen nicht einmal ein Array, wenn Sie einen einzelnen Element-Stream möchten. Sie können einfach 'Stream.of (Eintrag)' verwenden. Auf der anderen Seite brauchst du hier nicht einmal einen Stream. Sie können 'Optional.of (entry)' verwenden, die "map" - und "filter" -Operationen wie bei einem Stream verketten und statt '.count()> 0' '.isPresent()' verwenden. – Holger