标签:java java-stream side-effects
我正在尝试将有限数量的值流式传输到集合中,但我需要在应用限制之前验证它们是否是新元素.例如:
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
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。