flujo de Java: el uso del filtro opcional () en el encadenamiento de las operaciones

Alkis Mavridis:

Nota: esta pregunta es no relacionado con java.util.Optional.

Cuando se trata de corrientes, que a menudo utilizan la lógica de esta manera:

 Stream<FooBar> stream = myInitialStream();
 if (needsFilter1) stream = stream.filter(c -> whatever1());
 if (needsFilter2) stream = stream.filter(c -> whatever2());
 ...
 return stream.collect(toList());

Lo que estoy tratando de lograr es convertir el código anterior para una sola expresión utilizando el encadenamiento. Me parece más legible y sencillo. Hasta ahora, la única forma que encontró para lograr que era:

return myInitialStream()
       .filter(needsFilter1? c->whatever1() : c->true)
       .filter(needsFilter2? c->whatever2() : c->true)
       .collect(toList());

Sin embargo, esto haría llamadas innecesarias a esas triviales c->truelamdas, lo que podría producir algún costo rendimiento al aumento de escala.

Así que mi pregunta es: ¿hay una mejor manera de producir expresiones corriente encadenados que incluyen filtrado opcional?

ACTUALIZACIÓN: Tal vez no dejar claro lo suficiente, pero el punto de mi pregunta es encontrar una solución en una sola expresión . Si tengo que utilizar varias instrucciones (para inicializar un predicado, por ejemplo), que también podría utilizar el primer código de bloque de mi pregunta que básicamente hace lo mismo.

Nikolas:

Encadenar los predicados de acuerdo con las condiciones usando Predicate::andel retorno de una nueva predicado.

Predicate<FooBar> predicate = c -> whatever();

if (condition1) { predicate = predicate.and(c -> whatever1()); }
if (condition2) { predicate = predicate.and(c -> whatever2()); }

List<FooBar> dest = list.stream()
    .filter(predicate)
    .collect(Collectors.toList());

Tras una actualización que solicita una sola expresión. Usted necesita una fuente de condiciones asignadas a los predicados de todos modos. Con la estructura de datos Map<Supplier<Boolean>, Predicate<Integer>>, donde una clave es una Supplierde una condición de decidir si un valor ( Predicate<FooBar>se utiliza).

Reducir las entradas de un mapa a un nuevo Predicate<FooBar>utilizando el encadenamiento de éstas Predicatescon Predicate::and, por lo que sus Supplier<Boolean>rendimientos true(la condición es válida).

Tener una Mapde las condiciones:

Map<Supplier<Boolean>, Predicate<FooBar>> map = new HashMap<>();
map.put(() -> needsFilter1, c -> whatever1());
map.put(() -> needsFilter2, c -> whatever2());
...

Aquí hay una sola Streamdeclaración:

List<Integer> dest = list
        .stream()
        .filter(map.entrySet()                            // filter with a predicate ...
                .stream()
                .filter(e -> e.getKey().get())            // .. where a condition is 'true'
                .map(Entry::getValue)                     // .. get Predicates
                .reduce(i -> true, (l, r) -> l.and(r)))   // .. reduce them using AND
        .collect(Collectors.toList());               

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=172116&siteId=1
Recomendado
Clasificación