如何在没有isFinite()和isOrdered()方法的情况下安全地使用Java Streams?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了如何在没有isFinite()和isOrdered()方法的情况下安全地使用Java Streams?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3592字,纯文字阅读大概需要6分钟。
内容图文
有一个问题是java方法是否应该返回Collections or Streams,其中Brian Goetz回答即使对于有限序列,Streams通常应该是首选.
但在我看来,目前来自其他地方的Streams上的许多操作都无法安全执行,并且防御代码保护是不可能的,因为Streams不会显示它们是无限的还是无序的.
如果并行是我想要在Stream()上执行的操作的问题,我可以调用isParallel()来检查或顺序以确保计算是并行的(如果我记得).
但如果有序或有限(大小)与我的计划的安全性相关,我就不能写保护措施.
假设我使用了一个实现这个虚构接口的库:
public interface CoordinateServer {
public Stream<Integer> coordinates();
// example implementations:
// IntStream.range(0, 100).boxed() // finite, ordered, sequential
// final AtomicInteger atomic = new AtomicInteger();
// Stream.generate(() -> atomic2.incrementAndGet()) // infinite, unordered, sequential
// Stream.generate(() -> atomic2.incrementAndGet()).parallel() // infinite, unordered, parallel
}
然后我可以安全地在此流上调用哪些操作来编写正确的算法?
似乎我可能想将元素写入文件作为副作用,我需要关注并行流:
// if stream is parallel, which order will be written to file?
coordinates().peek(i -> {writeToFile(i)}).count();
// how should I remember to always add sequential() in such cases?
并且如果它是并行的,基于Threadpool并行的是什么?
如果我想对流(或其他非短路操作)进行排序,我不知何故需要谨慎对待它是无限的:
coordinates().sorted().limit(1000).collect(toList()); // will this terminate?
coordinates().allMatch(x -> x > 0); // will this terminate?
我可以在排序之前施加限制,但是如果我期望有限的未知大小的流,那么应该是哪个幻数?
最后,也许我想并行计算以节省时间然后收集结果:
// will result list maintain the same order as sequential?
coordinates().map(i -> complexLookup(i)).parallel().collect(toList());
但是如果没有对流进行排序(在该版本的库中),则由于并行处理,结果可能会变得严重.但除了不使用并行(这会破坏性能目的)之外,我怎么能防范这个?
集合是明确的有限或无限,关于是否有订单,并且它们不携带处理模式或线程池.这些似乎是API的宝贵属性.
另外,Streams may sometimes need to be closed,但最常见的不是.如果我从方法(来自方法参数)中使用流,我通常应该调用close吗?
此外,可能已经消耗了流,并且能够优雅地处理该情况将是好的,因此对于check if the stream has already been consumed来说这将是好事.
我希望有一些代码片段可用于在处理流之前验证关于流的假设,例如>
Stream<X> stream = fooLibrary.getStream();
Stream<X> safeStream = StreamPreconditions(
stream,
/*maxThreshold or elements before IllegalArgumentException*/
10_000,
/* fail with IllegalArgumentException if not ordered */
true
)
解决方法:
在我看到之后看了一些事情(一些实验和here),没有办法确定流是否是有限的.
除此之外,有时甚至在运行时除外(例如在java 11中 – IntStream.generate(() – > 1).takeWhile(x – > externalCondition(x))).
你能做的是:
>你可以通过几种方式确定它是否是有限的(注意在这些方面接收错误并不意味着它是无限的,只有它可能是这样):
> stream.spliterator().getExactSizeIfKnown() – 如果它具有已知的确切大小,则它是有限的,否则它将返回-1.
> stream.spliterator().hasCharacteristics(Spliterator.SIZED) – 如果是SIZED将返回true.
>你可以通过假设最坏的(取决于你的情况)来保护自己.
> stream.sequential()/ stream.parallel() – 显式设置首选消费类型.
>对于潜在的无限流,假设您在每种情况下都是最糟糕的情况.
>例如,假设您希望收听推文流,直到您在Venkat找到它 – 这是一个潜在的无限操作,但您想要等到找到这样的推文.所以在这种情况下,只需转到stream.filter(tweet – > isByVenkat(tweet)).findAny() – 它将迭代直到这样的推文出现(或永远).
>一个不同的场景,可能是更常见的场景,想要对所有元素做一些事情,或者只尝试一定的时间(类似于超时).为此,我建议在调用您的操作(collect或allMatch或类似)之前始终调用stream.limit(x),其中x是您愿意容忍的尝试量.
毕竟,我只想提一下,我认为返回一个流通常不是一个好主意,除非有很大的好处,否则我会尽量避免它.
内容总结
以上是互联网集市为您收集整理的如何在没有isFinite()和isOrdered()方法的情况下安全地使用Java Streams?全部内容,希望文章能够帮你解决如何在没有isFinite()和isOrdered()方法的情况下安全地使用Java Streams?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。