Spliterator vs Stream.Builder

Lucio:

He leído algunas de las preguntas de cómo crear un finitos Stream( Finite genera corriente en Java - cómo crear uno? , ¿Cómo corrientes parada? ).

Las respuestas sugeridas para implementar una Spliterator. El Spliteratorsería implementar la lógica de cómo y qué elemento para proporcionar como siguiente ( tryAdvance). Pero hay otros dos métodos no predeterminados trySplity estimateSize()los que me tendrían que poner en práctica.

El JavaDoc de Spliteratordice:

Un objeto para atravesar y los elementos de una fuente de partición. La fuente de los elementos de cubierta por una Spliteratorpodría ser, por ejemplo, una matriz, una Collection, un canal IO, o una función de generador. ... El SpliteratorAPI fue diseñado para apoyar el recorrido paralelo eficiente, además de recorrido secuencial, mediante el apoyo a la descomposición, así como iteración de un solo elemento. ...

Por otro lado pude implementar la lógica de la manera de avanzar al siguiente elemento en torno a una Stream.Buildery bypass una Spliterator. En cada avance que yo llamaría accepto addy al final build. Así que parece bastante simple.

¿Qué dice la JavaDoc?

Un constructor mutable para una Stream. Esto permite la creación de una Streammediante la generación de elementos de forma individual y añadiéndolos a la Builder(sin la sobrecarga de copiar que proviene del uso de un ArrayListcomo un búfer temporal.)

Usando StreamSupport.streamPuedo utilizar una Spliteratorpara obtener una Stream. Y también un Builderproporcione será una Stream.

Cuando debería / podría utilizar una Stream.Builder?
Sólo si un Spliteratorno habría más eficiente (por ejemplo, porque la fuente no puede ser dividida y su tamaño no puede ser estimado)?

Holger:

Tenga en cuenta que se puede extender Spliterators.AbstractSpliterator. A continuación, sólo hay tryAdvanceque poner en práctica.

Por lo que la complejidad de la implementación de un Spliteratorno es más alta.

La diferencia fundamental es que un Spliterator's tryAdvancemétodo sólo se invoca cuando se necesita un nuevo elemento. Por el contrario, el Stream.Buildertiene un almacenamiento que se llenará con todos los elementos de flujo, antes de poder adquirir un arroyo.

Por lo que una Spliteratores la primera opción para todo tipo de evaluación perezosa, así como cuando se tiene un almacenamiento existente quiere realizar el desplazamiento, para evitar la copia de los datos.

El constructor es la primera opción cuando la creación de los elementos no es uniforme, por lo que no se puede expresar la creación de un elemento bajo demanda. Pensar en situaciones en las que usaría otra manera Stream.of(…), pero resulta ser que inflexibles.

Por ejemplo, que tiene Stream.of(a, b, c, d, e), pero ahora resulta que, cy dson opcionales. Así que la solución es

Stream.Builder<MyType> builder = Stream.builder();
builder.add(a).add(b);
if(someCondition) builder.add(c).add(d);
builder.add(e).build()
   /* stream operations */

Otros casos de uso son esta respuesta , donde una Consumerse necesitaba para consultar un spliterator existente y empuje la parte posterior a un valor Streamdespués, o esta respuesta , en una estructura sin acceso aleatorio (una jerarquía de clases) debe ser transmitido en el orden opuesto.

Supongo que te gusta

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