las operaciones de ruta intermedio no evaluado en el recuento

atalantus :

Parece que estoy teniendo problemas para entender cómo Java compone las operaciones de rutas en una tubería corriente.

Al ejecutar el siguiente código

public
 static void main(String[] args) {
    StringBuilder sb = new StringBuilder();

    var count = Stream.of(new String[]{"1", "2", "3", "4"})
            .map(sb::append)
            .count();

    System.out.println(count);
    System.out.println(sb.toString());
}

La consola sólo imprime 4. El StringBuilderobjeto todavía tiene el valor "".

Cuando agrego el funcionamiento del filtro: filter(s -> true)

public static void main(String[] args) {
    StringBuilder sb = new StringBuilder();

    var count = Stream.of(new String[]{"1", "2", "3", "4"})
            .filter(s -> true)
            .map(sb::append)
            .count();

    System.out.println(count);
    System.out.println(sb.toString());
}

La salida cambia a:

4
1234

¿Cómo cambia el funcionamiento del filtro aparentemente redundante el comportamiento de flujo de la tubería compuesta?

JB Nizet:

El count()funcionamiento del terminal, en mi versión del JDK, termina ejecutando el código siguiente:

if (StreamOpFlag.SIZED.isKnown(helper.getStreamAndOpFlags()))
    return spliterator.getExactSizeIfKnown();
return super.evaluateSequential(helper, spliterator);

Si hay una filter()operación en la tubería de las operaciones, el tamaño de la corriente, que se conoce en un principio, no puede ser conocido más (ya que filterpodría rechazar algunos elementos de la corriente). Así que el ifbloque no se ejecuta, las operaciones intermedias son ejecutados y el StringBuilder es, pues, modificarse.

Por otro lado, si sólo se tiene map()en la tubería, el número de elementos de la corriente se garantiza que sea el mismo que el número inicial de elementos. Por lo que el bloque es ejecutado si, y el tamaño se devuelve directamente sin evaluar las operaciones intermedias.

Tenga en cuenta que el lambda pasado a map()viola el contrato se define en la documentación: se supone que debe ser una, operación que no interfiere sin estado, pero no es sin estado. Así que tener un resultado diferente en ambos casos no se puede considerar como un error.

Supongo que te gusta

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