java 8 - How do streams stop? -
i wondering when created own infinite stream stream.generate
how streams in standard library stop...
for example when have list records:
list<record> records = getlistwithrecords(); records.stream().foreach(/* */);
the stream won't infinite , running forever, stop when items in list traversed. how work? same functionality applies stream created files.lines(path)
(source: http://www.mkyong.com/java8/java-8-stream-read-a-file-line-by-line/).
and second question, how can stream created stream.generate
stopped in same manner then?
finite streams aren’t created via stream.generate
.
the standard way of implementing stream, implement spliterator
, using the iterator
detour. in either case, implementation has way report end, e.g. when spliterator.tryadvance
returns false
or foreachremaining
method returns, or in case of iterator
source, when hasnext()
returns false
.
a spliterator
may report expected number of elements before processing begins.
streams, created via 1 of factory methods inside stream
interface, stream.generate
may implemented either, spliterator
or using internal features of stream implementation, regardless of how implemented, don’t hands on implementation change behavior, way make such stream finite, chain limit
operation stream.
if want create non-empty finite stream not backed array or collection , none of existing stream sources fits, have implement own spliterator
, create stream out of it. told above, can use existing method create spliterator
out of iterator
, should resists temptation use iterator
because it’s familiar. spliterator
not hard implement:
/** {@code stream.generate}, intrinsic limit */ static <t> stream<t> generate(supplier<t> s, long count) { return streamsupport.stream( new spliterators.abstractspliterator<t>(count, spliterator.sized) { long remaining=count; public boolean tryadvance(consumer<? super t> action) { if(remaining<=0) return false; remaining--; action.accept(s.get()); return true; } }, false); }
from starting point, can add overrides default
methods of spliterator
interface, weighting development expense , potential performance improvements, e.g.
static <t> stream<t> generate(supplier<t> s, long count) { return streamsupport.stream( new spliterators.abstractspliterator<t>(count, spliterator.sized) { long remaining=count; public boolean tryadvance(consumer<? super t> action) { if(remaining<=0) return false; remaining--; action.accept(s.get()); return true; } /** may improve performance of non-short-circuiting operations */ @override public void foreachremaining(consumer<? super t> action) { long togo=remaining; remaining=0; for(; togo>0; togo--) action.accept(s.get()); } }, false); }
Comments
Post a Comment