我可以说java.util.stream.Stream中的peek()方法应该是幂等的

时间:2018-04-28 21:49:45

标签: java-stream idempotent peek

我的问题与:What does idempotent method mean and what are the side effects in case of calling close method of java.lang.AutoCloseable?

有关

关于java.util.stream.Stream.peek()中的方法,在Oracle Certified Professional Java SE 8 Study Guide一书中>第4章功能编程>使用Streams>使用通用中间操作,声明 peek()旨在执行操作而不更改结果

我的问题是:我可以说在实践中,即使有状态代码,偷看(消费者行为)中的操作应该是幂等的peek()中可以编译吗?

2 个答案:

答案 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()); 不是幂等的,因为每次调用都会产生一个新的输出行。

相关问题