Supongamos que tengo una secuencia de Cosas y quiero "enriquecerlas" a mitad de la secuencia, puedo usar peek()
para hacer esto, por ejemplo:
streamOfThings.peek(this::thingMutator).forEach(this::someConsumer);
Suponga que mutar las cosas en este punto del código es un comportamiento correcto; por ejemplo, el thingMutator
método puede establecer el campo "lastProcessed" en la hora actual.
Sin embargo, peek()
en la mayoría de los contextos significa "mirar, pero no tocar".
¿Está utilizando peek()
para mutar elementos de la corriente un antipatrón o mal aconsejado?
Editar:
El enfoque alternativo, más convencional, sería convertir al consumidor:
private void thingMutator(Thing thing) {
thing.setLastProcessed(System.currentTimeMillis());
}
a una función que devuelve el parámetro:
private Thing thingMutator(Thing thing) {
thing.setLastProcessed(currentTimeMillis());
return thing;
}
y usar map()
en su lugar:
stream.map(this::thingMutator)...
Pero eso introduce código superficial (the return
) y no estoy convencido de que sea más claro, porque sabes que peek()
devuelve el mismo objeto, pero con map()
ni siquiera es claro de un vistazo que es la misma clase de objeto.
Además, con peek()
usted puede tener una lambda que muta, pero con map()
usted tiene que construir un choque de trenes. Comparar:
stream.peek(t -> t.setLastProcessed(currentTimeMillis())).forEach(...)
stream.map(t -> {t.setLastProcessed(currentTimeMillis()); return t;}).forEach(...)
Creo que la peek()
versión es más clara y la lambda está claramente mutando, por lo que no hay ningún efecto secundario "misterioso". Del mismo modo, si se usa una referencia de método y el nombre del método implica claramente una mutación, eso también es claro y obvio.
En una nota personal, no evito usar peek()
para mutar, me parece muy conveniente.
peek
una secuencia que genera sus elementos dinámicamente? ¿Sigue funcionando o se pierden los cambios? Modificar los elementos de una transmisión no me parece confiable.
List<Thing> list; things.stream().peek(list::add).forEach(...);
muy útil. Últimamente. Lo he utilizado para agregar información de la publicación: Map<Thing, Long> timestamps = ...; return things.stream().peek(t -> t.setTimestamp(timestamp.get(t))).collect(toList());
. Sé que hay otras formas de hacer este ejemplo, pero estoy simplificando demasiado aquí. El uso peek()
produce un código más compacto y elegante en mi humilde opinión. Dejando a un lado la legibilidad, esta pregunta es realmente sobre lo que ha planteado; ¿es seguro / confiable?
peek
? Tengo una pregunta similar sobre stackoverflow y espero que puedas verla y dar tu opinión. Gracias. stackoverflow.com/questions/47356992/…