2017-02-23 4 views
1

In Java 8, ist es eine Möglichkeit, den Filter auf einem Strom auf der Grundlage einer Bedingung anzuwenden,Java 8 Anwenden von Stromfilter auf der Grundlage einer Bedingung

Beispiel

ich diesen Strom haben

if (isAccessDisplayEnabled) { 
    src = (List <Source>) sourceMeta.getAllSources.parallelStream() 
     .filter(k - > isAccessDisplayEnabled((Source) k)) 
     .filter(k - > containsAll((Source) k, substrings, searchString)) 
     .collect(Collectors.toList()); 
} else { 
    src = (List <Source>) sourceMeta.getAllSources.parallelStream() 
     .filter(k - > containsAll((Source) k, substrings, searchString)) 
     .collect(Collectors.toList()); 
} 

ich füge den Filter

.filter (k -> isAccessDisplayEnabled ((Quelle) k)))

im Stream basierend auf der if-else-Bedingung. Gibt es eine Möglichkeit, dies zu vermeiden, wenn es sonst noch mehr Filter gibt, dann wird es schwer zu pflegen sein.

Bitte lassen Sie mich wissen

Antwort

7

Eine Möglichkeit, es zu tun ist

Stream<Source> stream = sourceMeta.getAllSources.parallelStream().map(x -> (Source)x); 
if(isAccessDisplayEnabled) stream = stream.filter(s -> isAccessDisplayEnabled(s)); 
src = stream.filter(s - > containsAll(s, substrings, searchString)) 
      .collect(Collectors.toList()); 

andere

src = sourceMeta.getAllSources.parallelStream().map(x -> (Source)x) 
    .filter(isAccessDisplayEnabled? s - > isAccessDisplayEnabled(s): s -> true) 
    .filter(s - > containsAll(s, substrings, searchString)) 
    .collect(Collectors.toList()); 

In jedem Fall ist zu beachten, wie zu Beginn eine Art Guss Durchführung des pipline gesamten Strom vereinfacht.

Beide Lösungen vermeiden die Neubewertung von isAccessDisplayEnabled für jedes Stream-Element. Die zweite Lösung beruht jedoch auf der Fähigkeit der JVM, s -> true zu inlinern, wenn sich dieser Code als leistungskritisch erweist.

+0

Ich bin nicht in der Lage, diese Zeile zu verstehen, isAccessDisplayEnabled? s -> true: s -> isAccessDisplayEnabled (s), bitte erklären Sie ein bisschen mehr oder zu einem Blog, der es erklärt. – Umar

+0

Versuchen Sie, es als 'isAccessDisplayEnabled zu lesen? (s -> true): (s -> isAccessDisplayEnabled (s)) '. Wenn 'isAccessDisplayEnabled'' true' ist, benutze den Lambda-Ausdruck 's -> true', was im Prinzip so aussieht, als ob du keinen Filter hast, andernfalls benutze' s -> isAccessDisplayEnabled (s) '. Es ist eine Kombination des [ternary operator] (https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html) mit zwei alternativen [Lambda-Ausdrücken] (http://docs.oracle.com/ javase/tutorial/java/java00/lambdaeexpressions.html). – Holger

+0

@Holder: ok für ternary aber Ordnung ist falsch, nein? Ich denke, wenn Sie eine boolean isAccessDisplayEnabled haben, dann möchten Sie filtern, andernfalls wenn Sie nicht filtern. 'isAccessDisplayEnabled? (s -> isAccessDisplayEnabled (s)): (s -> true) ' – sandwood

2

Ihr Zustand den gleichen Namen wie Ihre Methode hat. Ich werde dich zu übernehmen bedeutet für diejenigen, anders zu sein, also lassen Sie uns sagen, dass es das war:

if (someCondition) { 
    src = (List <Source>) sourceMeta.getAllSources.parallelStream() 
     .filter(k - > isAccessDisplayEnabled((Source) k)) 
     .filter(k - > containsAll((Source) k, substrings, searchString)) 
     .collect(Collectors.toList()); 
} else { 
    src = (List <Source>) sourceMeta.getAllSources.parallelStream() 
     .filter(k - > containsAll((Source) k, substrings, searchString)) 
     .collect(Collectors.toList()); 
} 

Wenn Sie die if/else entfernen möchten, können Sie stattdessen die Prüfung im ersten Filter durchführen:

src = (List <Source>) sourceMeta.getAllSources.parallelStream() 
    .filter(k - > !someCondition || isAccessDisplayEnabled((Source) k)) 
    .filter(k - > containsAll((Source) k, substrings, searchString)) 
    .collect(Collectors.toList()); 

im anderen Fall, nehmen Sie alles und die isAccessDisplayEnabled() -Methode entfernen, so ist die Bedingung wirksam „wenn someCondition falsch oder isAccessDisplayEnabled (k)“. Wenn someCondition false ausgibt, wird die Überprüfung von isAccessDisplayEnabled() übersprungen.

+2

... aber 'someCondition' kann für jedes Element neu bewertet werden. – Holger

+2

Eine Variable und eine Methode können in Java den gleichen Namen haben. Java ist in diesem Sinne Lisp 2. ;) –

+0

@DavidConrad Ich bin mir sicher, dass das stimmt, aber ich glaube nicht, dass er es so gemeint hat. Ich habe gerade den Variablennamen geändert, um Dinge zu klären. – jchitel

Verwandte Themen