问题
I know there is infinite stream in Java.
Is there a way to check whether the stream is finite or not?
Something like this method 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();
}
The construction of the Stream would leave some marks/tracks that we can use to trace back to check it?
The checking method could work always as expected reliably?
Update
I was wrong about this when trying to solve a problem by detecting the isFinite
of a stream. It seems it's not stable/reliable as the answers mentioned. I will refactor my solution in another around. Thank you for the help ~
回答1:
There is no reliable way to do it. Even using the estimateSize
, which is documented:
... or returns Long.MAX_VALUE if infinite, unknown, or too expensive to compute.
So simply relying on the fact that Long.MAX_VALUE
will tell you if this stream is infinite or not - is simply wrong.
The other suggestion says that to use SIZED
, which is again wrong:
IntStream.generate(() -> 1).limit(5)
You know that this is a SIZED
stream - the implementation does not and will not report the sized flag.
Bottom-line: you can't in a reliable way. Theoretically this could be possible for some cases, like when you just use generate
without limiting or short-circuiting the stream, the implementation could register a flag like IS_INFINITE
or something, but this IMO would be useless, probably for 99% of the cases.
You can also think in reverse here, how about when you want to tell with certainty if this stream is finite? In such a case, getExactSizeIfKnown()
would tell you that.
回答2:
There is no way to check if a stream is infinite with certainty, but there is a way to detect if it's finite with certainty.
[fixed] I had it the wrong way around.
/**
* 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;
}
Javadoc of estimateSize()
:
Returns an estimate of the number of elements that would be encountered by a
forEachRemaining
traversal, or returnsLong.MAX_VALUE
if infinite, unknown, or too expensive to compute.
来源:https://stackoverflow.com/questions/51026731/is-there-a-way-to-check-whether-a-stream-is-finite-in-java