我知道Java中存在无限流。
是否可以检查流是否有限?
类似isStreamFinite(Stream<T> stream)
的方法吗?
@Test
public void testStreamFinity() {
assertFalse(isStreamFinite(generateLong()));
}
private <T> boolean isStreamFinite(Stream<T> stream) {
if (stream.count() < Long.MAX_VALUE) {
return true;
}
return false;
}
private Stream<Long> generateLong() {
return LongStream.generate(() -> new Random().nextLong()).boxed();
}
流的构造会留下一些标记/轨道,我们可以使用它们来追溯以进行检查?
检查方法是否可以始终可靠地按预期工作?
在尝试通过检测流的isFinite
解决问题时,我对此有误。所提到的答案似乎并不稳定/可靠。我将在其他地方重构我的解决方案。谢谢你的帮助〜
答案 0 :(得分:7)
没有可靠的方法来做到这一点。甚至使用estimateSize
,该文件已记录在案:
...,如果无限,未知或计算成本过高,则返回Long.MAX_VALUE。
因此,仅仅依靠Long.MAX_VALUE
会告诉您此流是否无限的事实是完全错误的。
另一个建议是使用SIZED
,这又是错误的:
IntStream.generate(() -> 1).limit(5)
您知道这是一个SIZED
流-该实现不会并且将不报告大小标志。
底线:您无法以可靠的方式。从理论上讲,在某些情况下这是可能的,例如当您仅使用generate
而没有限制或短路流时,实现可以注册一个IS_INFINITE
之类的标志,但是此IMO可能毫无用处,可能在99%的情况下都是如此。
您在这里也可以反过来思考,如果您想确定地确定此流是否有限,该怎么办?在这种情况下,getExactSizeIfKnown()
会告诉您。
答案 1 :(得分:2)
无法检查流是否为确定性无限,但是有一种方法可以检测到流是否为确定性。
[已修复]我的输入方法错误。
/**
* When this returns {@code true}, the stream is finite for sure. Otherwise the
* stream could be either infinite or finite.
*/
private static <T> boolean isStreamFinite(Stream<T> stream) {
return stream.spliterator().estimateSize() != Long.MAX_VALUE;
}
estimateSize()
的Javadoc:
返回
forEachRemaining
遍历将遇到的元素数量的估计值,如果无限,未知或计算成本太高,则返回Long.MAX_VALUE
。