在这种情况下,只有奇数行有意义的数据,并且没有唯一标识这些行的字符.我的目的是获得与以下示例相当的东西:
Stream<DomainObject> res = Files.lines(src) .filter(line -> isOddLine()) .map(line -> toDomainObject(line))
有没有任何“干净”的做法,没有分享全球国家?
解决方法
一个干净的方法是进一步深入实现一个Spliterator.在这个级别上,您可以通过流元素控制迭代,并且只要下游请求一个项目,只需迭代两个项目:
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) {} }
那么你可以使用它
Stream<DomainObject> res = OddLines.oddLines(Files.lines(src)) .map(line -> toDomainObject(line));
该解决方案没有副作用,并保留了Stream API的最大优势,就像懒惰的评估.然而,应该清楚的是,它对于无序流处理没有一个有用的语义(请注意在对所有元素执行终端操作时使用forEachOrdered而不是forEach的微妙方面),并且原则上支持并行处理的可能性不大非常有效…