如何跳过 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) {}
}
那么你就可以像这样使用它了
Then you can use it like
Stream<DomainObject> res = OddLines.oddLines(Files.lines(src))
.map(line -> toDomainObject(line));
此解决方案没有副作用,并保留了 Stream
API 的大部分优点,例如惰性求值.但是,应该清楚的是,它对于无序流处理没有有用的语义(请注意在执行终端操作时使用 forEachOrdered
而不是 forEach
所有元素)并且虽然原则上支持并行处理,但它不太可能非常有效......
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屋!