java 8 - How to skip even lines of a Stream<String> obtained from the Files.lines -
in case odd lines have meaningful data , there no character uniquely identifies lines. intention equivalent following example:
stream<domainobject> res = files.lines(src) .filter(line -> isoddline()) .map(line -> todomainobject(line)) is there “clean” way it, without sharing global state?
a clean way go 1 level deeper , implement spliterator. on level can control iteration on stream elements , iterate on 2 items whenever downstream requests 1 item:
public class oddlines<t> extends spliterators.abstractspliterator<t> implements consumer<t> { public static <t> stream<t> oddlines(stream<t> source) { return streamsupport.stream(new oddlines(source.spliterator()), false); } private static long odd(long l) { return l==long.max_value? l: (l+1)/2; } spliterator<t> originallines; oddlines(spliterator<t> source) { super(odd(source.estimatesize()), source.characteristics()); originallines=source; } @override public boolean tryadvance(consumer<? super t> action) { if(originallines==null || !originallines.tryadvance(action)) return false; if(!originallines.tryadvance(this)) originallines=null; return true; } @override public void accept(t t) {} } then can use like
stream<domainobject> res = oddlines.oddlines(files.lines(src)) .map(line -> todomainobject(line)); this solution has no side effects , retains advantages of stream api lazy evaluation. however, should clear hasn’t useful semantics unordered stream processing (beware subtle aspects using foreachordered rather foreach when performing terminal action on elements) , while supporting parallel processing in principle, it’s unlikely efficient…
Comments
Post a Comment