关于java.util.stream.Stream.peek()
中的方法,在Oracle Certified Professional Java SE 8 Study Guide一书中>第4章功能编程>使用Streams>使用通用中间操作,声明 peek()旨在执行操作而不更改结果
我的问题是:我可以说在实践中,即使有状态代码,偷看(消费者行为)中的操作应该是幂等的在peek()
中可以编译吗?
答案 0 :(得分:0)
你不应该因为这意味着操作可以改变最终结果,因为幂等操作可以mutate the object it operates on。
以下示例在peek()
方法中使用幂等操作,但更改结果(根据您指出的文档,这不是一个好习惯)
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class SomeClass {
private String state = "some-value";
public void idempotent() {
state = "other-value";
}
@Override
public String toString() {
return "SomeClass{" +
"state='" + state + '\'' +
'}';
}
}
public class Idempotent {
public static void main(String[] args) {
Set<SomeClass> collect = Stream.of(new SomeClass(), new SomeClass())
.peek(SomeClass::idempotent)
.collect(Collectors.toSet());
System.out.println(collect);
}
}
在peek()
操作之前,流由["some-value", "some-value]
组成,在peek()
之后进行幂等操作,它由["other-value", "other-value"]
组成。
答案 1 :(得分:0)
Javadoc说它应该是non-interfering,而不是幂等,这不是一回事。
事实上,由于它必须是非干扰性的,并且只能通过副作用进行操作,因此很可能它不是幂等的。
API note甚至清楚地显示了一个非幂等用法示例:
此方法主要用于支持您要查看的调试 当元素流过管道中的某个点时:
print(data, ...); printjson(object); print(JSON.stringify(object));
如您所知,Stream.of("one", "two", "three", "four")
.filter(e -> e.length() > 3)
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.collect(Collectors.toList());
不是幂等的,因为每次调用都会产生一个新的输出行。