web-dev-qa-db-fra.com

Java 8 Application d'un filtre de flux en fonction d'une condition

En Java 8, existe-t-il un moyen d’appliquer le filtre sur un flux en fonction d’une condition,

exemple

J'ai ce flux

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());
 }

J'ajoute le filtre 

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

sur le flux en fonction de la condition if-else. Y a-t-il un moyen d'éviter cela si-sinon, car s'il y a plus de filtres à venir, alors ce sera difficile à maintenir.

S'il vous plaît, faites-moi savoir

7
Umar

Une façon de le faire est

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());

un autre

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

Dans les deux cas, notez comment l'exécution d'une conversion de type au début simplifie l'ensemble du code du flux.

Les deux solutions évitent de réévaluer isAccessDisplayEnabled pour chaque élément de flux. Toutefois, la seconde repose sur la capacité de la JVM d’ajouter s -> true lorsque ce code s'avère critique pour la performance.

11
Holger

Votre condition porte le même nom que votre méthode. Je vais supposer que vous vouliez dire que ceux-ci sont différents, alors disons que c'était ceci:

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());
}

Si vous souhaitez supprimer le if/else, vous pouvez plutôt effectuer la vérification dans le premier filtre:

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

Dans le cas contraire, vous prenez tout et supprimez l'appel de méthode isAccessDisplayEnabled (). La condition est donc effectivement "si someCondition est false ou isAccessDisplayEnabled (k)". Si une condition est fausse, la vérification isAccessDisplayEnabled () est ignorée.

2
jchitel