Misalkan saya memiliki aliran Things dan saya ingin "memperkaya" mereka mid stream, saya dapat menggunakannya peek()
untuk melakukan ini, misalnya:
streamOfThings.peek(this::thingMutator).forEach(this::someConsumer);
Asumsikan bahwa mutasi Hal pada titik ini dalam kode adalah perilaku yang benar - misalnya, thingMutator
metode ini dapat menetapkan bidang "lastProcessed" ke waktu saat ini.
Namun, peek()
dalam sebagian besar konteks berarti "lihat, tapi jangan sentuh".
Apakah menggunakan peek()
untuk mengubah elemen stream adalah antipattern atau keliru?
Edit:
Alternatifnya, yang lebih konvensional, adalah mengubah konsumen:
private void thingMutator(Thing thing) {
thing.setLastProcessed(System.currentTimeMillis());
}
ke fungsi yang mengembalikan parameter:
private Thing thingMutator(Thing thing) {
thing.setLastProcessed(currentTimeMillis());
return thing;
}
dan gunakan map()
sebagai gantinya:
stream.map(this::thingMutator)...
Tapi itu memperkenalkan kode ala kadarnya ( return
dan) dan saya tidak yakin itu lebih jelas, karena Anda tahu peek()
mengembalikan objek yang sama, tetapi dengan map()
itu bahkan tidak jelas sekilas bahwa itu adalah kelas objek yang sama.
Selanjutnya, dengan peek()
Anda dapat memiliki lambda yang bermutasi, tetapi dengan map()
Anda harus membangun bangkai kereta. Membandingkan:
stream.peek(t -> t.setLastProcessed(currentTimeMillis())).forEach(...)
stream.map(t -> {t.setLastProcessed(currentTimeMillis()); return t;}).forEach(...)
Saya pikir peek()
versinya lebih jelas, dan lambda jelas bermutasi, jadi tidak ada efek samping "misterius". Demikian pula, jika referensi metode digunakan dan nama metode jelas menyiratkan mutasi, itu juga jelas dan jelas.
Pada catatan pribadi, saya tidak menghindar dari penggunaan peek()
untuk bermutasi - Saya merasa sangat nyaman.
peek
aliran yang menghasilkan elemen-elemennya secara dinamis? Apakah masih berfungsi, atau perubahannya hilang? Mengubah elemen aliran terdengar tidak dapat diandalkan bagi saya.
List<Thing> list; things.stream().peek(list::add).forEach(...);
sangat berguna. Belakangan ini. Aku sudah menggunakannya untuk menambahkan info untuk penerbitan: Map<Thing, Long> timestamps = ...; return things.stream().peek(t -> t.setTimestamp(timestamp.get(t))).collect(toList());
. Saya tahu ada cara lain untuk melakukan contoh ini, tetapi saya sangat menyederhanakan di sini. Menggunakan peek()
menghasilkan IMHO kode yang lebih kompak, dan lebih elegan. Selain keterbacaan, pertanyaan ini sebenarnya tentang apa yang Anda ajukan; apakah aman / dapat diandalkan?
peek
? Saya punya pertanyaan serupa tentang stackoverflow dan berharap Anda bisa melihatnya dan memberikan tanggapan Anda. Terima kasih. stackoverflow.com/questions/47356992/…