如何跳过Stream< String>的偶数行从Files.lines获得 [英] How to skip even lines of a Stream<String> obtained from the Files.lines
问题描述
在这种情况下,奇数行只有有意义的数据,并且没有唯一标识这些行的字符。我的目的是获得与以下示例等效的内容:
In this case just odd lines have meaningful data and there is no character that uniquely identifies those lines. My intention is to get something equivalent to the following example:
Stream<DomainObject> res = Files.lines(src)
.filter(line -> isOddLine())
.map(line -> toDomainObject(line))
在没有共享全局状态的情况下,有没有干净的方法呢?
Is there any "clean" way to do it, without sharing global state?
推荐答案
一个干净的方法是更深层次并实现 Spliterator
。在这个级别上,您可以控制流元素的迭代,只需在下游请求一个项目时迭代两个项目:
A clean way is to go one level deeper and implement a Spliterator
. On this level you can control the iteration over the stream elements and simply iterate over two items whenever the downstream requests one 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) {}
}
然后你就可以使用它了
Stream<DomainObject> res = OddLines.oddLines(Files.lines(src))
.map(line -> toDomainObject(line));
此解决方案没有副作用,并保留了 Stream的大部分优势
API就像懒惰评估一样。但是,应该很清楚它对于无序流处理没有有用的语义(注意使用 forEachOrdered
而不是 forEach的微妙方面) / code>在对所有元素执行终端操作时)并且原则上支持并行处理时,它不太可能非常有效...
This solution has no side effects and retains most advantages of the Stream
API like the lazy evaluation. However, it should be clear that it hasn’t a useful semantics for unordered stream processing (beware about the subtle aspects like using forEachOrdered
rather than forEach
when performing a terminal action on all elements) and while supporting parallel processing in principle, it’s unlikely to be very efficient…
这篇关于如何跳过Stream< String>的偶数行从Files.lines获得的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!