编程语言
首页 > 编程语言> > java – 连续流操作是否有副作用?

java – 连续流操作是否有副作用?

作者:互联网

我正在尝试将有限数量的值流式传输到集合中,但我需要在应用限制之前验证它们是否是新元素.例如:

Set<Integer> destination = ... 
Set<Integer> source = ...
source.stream()
        .filter(i -> !destination.contains(i))
        .limit(10)
        .forEach(destination::add);

但冗余的contains()检查让我烦恼,因为add()可以添加元素并报告它是否是集合的新内容.所以我想这样做:

source.stream()
        .filter(destination::add)
        .limit(10)
        .forEach(i -> {});    // no-op terminal operation to force evaluation

忽略hacky终端操作,存在使用具有副作用的过滤操作的问题,这通常是不鼓励的.我理解为什么在并行流上使用带有副作用的map()和filter()是不安全的.我的问题是,在顺序流上是否可以接受,就像在这种情况下一样?如果没有,为什么不呢?

解决方法:

副作用和顺序流没有根本问题,但上面的第二个实现是无效的,因为流API不保证每个元素将依次在每个元素上执行.

在第二种实现中,在应用限制之前,可以向目的地添加10个以上的元素.你的无操作forEach只会看到10,但你最终可能会得到更多.

除了流之外,java还有像for和while这样的循环结构,可以很容易地表达这样的东西.

如果必须使用流,可以这样做:

int maxSize = destination.size()+10;
source.stream().allMatch(x -> destination.size()<maxsize && (destination.add(x)||true));

一旦谓词返回false,allMatch将停止迭代.

标签:java,java-stream,side-effects
来源: https://codeday.me/bug/20190527/1166110.html