在Java中有没有一种方法可以检查流是否是有限的?

4

我知道在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解决问题时,我错了。正如答案中提到的那样,它似乎不稳定/可靠。我将采用另一种方式重构我的解决方案。谢谢你的帮助~


6
无法通用地解决此问题,只能确定流是如何构造的。请参考:https://en.wikipedia.org/wiki/Halting_problem - Peter Lawrey
你的方法有返回值吗? - shmosel
哈哈,当然不是~这只是一个演示,展示我正在尝试做什么。 - Hearen
3
我认为当确定某个流是无限的时候,可以引入一个类似于 generate 的标志;但这样做真正有什么价值呢?例如,对于 Files.lines,你的文件是否是“有限”的呢?我不知道为什么需要这样做。此外,Long.MAX_VALUE 除了用于表示无限流之外,在许多其他情况下也被使用。 - Eugene
2个回答

7
没有可靠的方法来做到这一点。即使使用文档记录的estimateSize,也无法确定:

......或者如果是无限的、未知的或计算代价太高,则返回Long.MAX_VALUE。

因此,仅仅依靠Long.MAX_VALUE会告诉您这个流是否无限是错误的。
另一个建议是使用SIZED,这也是错误的:
IntStream.generate(() -> 1).limit(5)

您知道这是一个SIZED流 - 实现不会报告大小标志。

重点:您无法可靠地做到这一点。在理论上,对于某些情况,比如当您使用generate而没有限制或短路该流时,实现可以注册一个类似IS_INFINITE的标志,但我认为这将是无用的,可能只适用于99%的情况。

您还可以反过来思考,在何种情况下您想要确定此流是否有限?在这种情况下,getExactSizeIfKnown()将告诉您。


3
请注意,没人知道 IntStream.generate(() -> 1) .takeWhile(x -> externalCondition(x)) 是否是有限的... - Holger
1
如果有一个IS_INFINITE标志,它允许实现将IntStream.generate(() -> 1).limit(5)示例转换为SIZED流。但对于外部代码来说,它没有太多用处,因为缺少此标志仍然不能保证流是有限的。 - Holger
@Holger 看起来比我想象的要复杂得多,我会重构我的解决方案。谢谢~ - Hearen

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


2
这可能是最好的猜测,但仍然只是一种猜测,没有可靠的方法来完成它。 - Eugene
5
您可以使用 getExactSizeIfKnown() >= 0 来检测其是否一定是有限的。 - Holger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接