实际任务是能够通过从文件中读取来返回一个 Stream,但这样做不会将整个文件(或已解析的集合)完全加载到内存中。该流的目的可以稍后确定——例如保存到数据库。开发人员将拥有反序列化流的句柄(而不是反序列化集合)。
问题是不能保证文件中的一行等于一个 MyEntity 对象(在这种情况下我可以使用这篇文章:http://blog.codeleak.pl/2014/05/parsing-file-with-stream-api-in-java-8.html)
通常,人们可能会发现这样一种情况,即提供输入流,需要返回通过将可变数量的输入流项映射到一个输出流项而构造的输出流。
到目前为止,我的解决方案是使用供应商,如下所示:
public class Parser{
public Stream<MyEntity> parse(final InputStream stream) {
return Stream.generate(new AggregatingSupplier(stream));
}
private class AggregatingSupplier implements Supplier<MyEntity> {
private final Scanner r;
public AggregatingSupplier(final InputStream source) {
this.r= new Scanner(source);
}
@Override
public MyEntity get() {
MyEntity re=new MyEntity();
while (r.hasNextLine() &&!re.isComplete()){
String line=r.nextLine();
// ... do some processing
}
return re;
}
}
}
这种方法的问题在于使用 Stream.generate 获得的流是无限的。没有停止条件。抛出异常有效(有点)。或者选择一种完全不同的(经典的)方法。
最佳答案
考虑实现自定义 Spliterator
而不是 Supplier
。它并没有乍一看那么令人生畏(通过检查 Spliterator
接口(interface)),因为 Spliterators.AbstractSpliterator
基类使它变得非常简单:只需提供 tryAdvance()
,它看起来与您现在在 Supplier
中的基本相同。
停止条件变得简单:只需让 tryAdvance()
返回 false
。
关于Java 8 从输入流读取到输出流,同时聚合项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32137650/