在这种情况下,只有奇数行有意义的数据,并且没有唯一标识这些行的字符.我的目的是获得与以下示例相当的东西:
- 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的微妙方面),并且原则上支持并行处理的可能性不大非常有效…