Diyelim ki bir şeyler akışım var ve onları orta akışta "zenginleştirmek" istiyorum, bunu peek()
yapmak için kullanabilirim , örneğin:
streamOfThings.peek(this::thingMutator).forEach(this::someConsumer);
Şeylerin kodda bu noktada mutasyona tabi tutulmasının doğru bir davranış olduğunu varsayalım - örneğin, thingMutator
yöntem "lastProcessed" alanını şimdiki zamana ayarlayabilir.
Ancak, peek()
çoğu bağlamda "bak, ama dokunma" anlamına gelir.
Kullanarak mı peek()
hiç mutasyon akışı elemanları bir antipattern veya tedbirsiz?
Düzenle:
Alternatif, daha geleneksel yaklaşım, tüketiciyi dönüştürmek olacaktır:
private void thingMutator(Thing thing) {
thing.setLastProcessed(System.currentTimeMillis());
}
parametre döndüren bir işleve:
private Thing thingMutator(Thing thing) {
thing.setLastProcessed(currentTimeMillis());
return thing;
}
ve map()
bunun yerine kullanın:
stream.map(this::thingMutator)...
Ancak bu, perfunctory kodunu (the return
) tanıtır ve bunun daha açık olduğuna ikna olmadım, çünkü peek()
aynı nesneyi döndürdüğünü biliyorsunuz , ancak map()
bir bakışta aynı nesne sınıfı olduğu bile belli değil .
Ayrıca, peek()
mutasyona uğrayan bir lambdaya sahip olabilirsiniz, ancak map()
sizinle birlikte bir tren kazası yapmak zorundasınız. Karşılaştırmak:
stream.peek(t -> t.setLastProcessed(currentTimeMillis())).forEach(...)
stream.map(t -> {t.setLastProcessed(currentTimeMillis()); return t;}).forEach(...)
Bence peek()
sürüm daha net ve lambda açıkça mutasyona uğramış, bu yüzden "gizemli" bir yan etkisi yok. Benzer şekilde, eğer bir yöntem referansı kullanılırsa ve yöntemin adı açıkça mutasyon anlamına gelirse, bu da açık ve açıktır.
Kişisel bir notta, peek()
mutasyona uğramaktan çekinmekten çekinmiyorum - çok uygun buluyorum.
peek
Elementlerini dinamik olarak üreten bir akışla kullandınız mı ? Hala çalışıyor mu yoksa değişiklikler mi kayboluyor? Bir akıntının elemanlarını değiştirmek bana güvenilmez geliyor.
List<Thing> list; things.stream().peek(list::add).forEach(...);
çok kullanışlı. Son zamanlarda. Ben yayınladığı için bilgi eklemek kullandım: Map<Thing, Long> timestamps = ...; return things.stream().peek(t -> t.setTimestamp(timestamp.get(t))).collect(toList());
. Bu örneği yapmanın başka yolları olduğunu biliyorum, ama burada aşırı derecede basitleştiriyorum. peek()
IMHO kullanarak daha kompakt ve daha zarif kodlar üretir. Okunabilirlik bir yana, bu soru gerçekten neyi yetiştirdiğinizle ilgilidir; güvenli mi / güvenilir mi?
peek
? Stackoverflow'ta da benzer bir sorum var ve ona bakıp geri bildiriminizi verebileceğinizi umuyorum. Teşekkürler. stackoverflow.com/questions/47356992/…