Java 8 从输入流读取到输出流,同时聚合项

标签 java stream java-8 java-stream

实际任务是能够通过从文件中读取来返回一个 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/

相关文章:

Java/clojure : Multiple character delimiter, 并保留分隔符

java - 如何编写代码来查找数组中整数的众数,而不使用个人创建的方法,即常规的 "raw code"

java - Spring JPA REST 一对多

c++ - 加载格式化的二进制文件并将信息分配给结构 c++

java - 如何将 Map<String, List<Object>> 流式传输到 Stream<Entry<String, Object>> 中?

自动关闭资源的Java 8 Stream(基于资源).iterator()?

java - map 上的流过滤器和分组列表

java - 如何监控媒体播放器接收的网络流量

java - 检测压缩文件java

c++ - 从流中读取以初始化只读变量