Suponha que eu tenha um fluxo de coisas e que queira "enriquecê-los" no meio do fluxo, posso usar peek()isso, por exemplo:
streamOfThings.peek(this::thingMutator).forEach(this::someConsumer);
Suponha que a alteração das coisas neste momento no código seja um comportamento correto - por exemplo, o thingMutatormétodo pode definir o campo "lastProcessed" para o horário atual.
No entanto, peek()na maioria dos contextos significa "olhe, mas não toque".
O uso peek()para alterar elementos de fluxo é um antipadrão ou é desaconselhável?
Editar:
A abordagem alternativa, mais convencional, seria converter o consumidor:
private void thingMutator(Thing thing) {
thing.setLastProcessed(System.currentTimeMillis());
}
para uma função que retorna o parâmetro:
private Thing thingMutator(Thing thing) {
thing.setLastProcessed(currentTimeMillis());
return thing;
}
e use map():
stream.map(this::thingMutator)...
Mas isso introduz código superficial (the return) e não estou convencido de que seja mais claro, porque você sabe que peek()retorna o mesmo objeto, mas com map()isso nem fica claro à primeira vista que é a mesma classe de objeto.
Além disso, peek()você pode ter um lambda que sofre mutação, mas com map()você tem que construir um acidente de trem. Comparar:
stream.peek(t -> t.setLastProcessed(currentTimeMillis())).forEach(...)
stream.map(t -> {t.setLastProcessed(currentTimeMillis()); return t;}).forEach(...)
Eu acho que a peek()versão é mais clara e o lambda está claramente mudando, então não há efeito colateral "misterioso". Da mesma forma, se uma referência de método for usada e o nome do método implicar claramente uma mutação, isso também será claro e óbvio.
Em uma nota pessoal, não evito usar o peek()mutate - acho muito conveniente.
peekcom um fluxo que gera seus elementos dinamicamente? Ainda funciona ou as alterações são perdidas? Modificar os elementos de um fluxo parece pouco confiável para mim.
List<Thing> list; things.stream().peek(list::add).forEach(...);muito útil. Recentemente. Eu usei-o para adicionar informações para a publicação: Map<Thing, Long> timestamps = ...; return things.stream().peek(t -> t.setTimestamp(timestamp.get(t))).collect(toList());. Eu sei que existem outras maneiras de fazer esse exemplo, mas estou simplificando bastante aqui. Usar peek()produz código IMHO mais compacto e mais elegante. Legibilidade à parte, esta questão é realmente sobre o que você levantou; é seguro / confiável?
peek? Tenho uma pergunta semelhante sobre o stackoverflow e espero que você possa ver e dar seu feedback. Obrigado. stackoverflow.com/questions/47356992/…