假设我有一个事物流,并且想在流中“丰富”它们,我可以使用peek()
它,例如:
streamOfThings.peek(this::thingMutator).forEach(this::someConsumer);
假设在代码的这一点上对事物进行变异是正确的行为-例如,该thingMutator
方法可以将“ lastProcessed”字段设置为当前时间。
但是,peek()
在大多数情况下,它的意思是“看起来,但不要碰”。
是使用peek()
到发生变异流元素的反模式或不明智的?
编辑:
另一种更常规的方法是转换消费者:
private void thingMutator(Thing thing) {
thing.setLastProcessed(System.currentTimeMillis());
}
到返回参数的函数:
private Thing thingMutator(Thing thing) {
thing.setLastProcessed(currentTimeMillis());
return thing;
}
并map()
改用:
stream.map(this::thingMutator)...
但这会引入敷衍的代码(return
),但我不认为它会更清晰,因为您知道peek()
返回的对象相同,但是map()
乍一看并不清楚它是同一类对象。
此外,使用peek()
lambda可以突变,但是map()
您必须构建火车残骸。比较:
stream.peek(t -> t.setLastProcessed(currentTimeMillis())).forEach(...)
stream.map(t -> {t.setLastProcessed(currentTimeMillis()); return t;}).forEach(...)
我认为peek()
版本更清晰,lambda也很明显是变异的,因此没有“神秘的”副作用。同样,如果使用方法引用,并且该方法的名称明确暗含了突变,则该名称也很明显。
就个人而言,我不会回避使用peek()
变异-我觉得这很方便。
peek
了动态生成其元素的流?它仍然有效,还是所做的更改丢失了?修改流元素对我来说听起来不可靠。
List<Thing> list; things.stream().peek(list::add).forEach(...);
非常方便。最近。我用它来添加发布信息:Map<Thing, Long> timestamps = ...; return things.stream().peek(t -> t.setTimestamp(timestamp.get(t))).collect(toList());
。我知道还有其他方法可以执行此示例,但是在这里我大大简化了。使用peek()
产生更紧凑,更优雅的代码恕我直言。除了可读性,这个问题实际上与您提出的内容有关。安全/可靠吗?
peek
?我对stackoverflow也有类似的问题,希望您可以看一下并提供反馈。谢谢。stackoverflow.com/questions/47356992/…–