Java 处理一个大文件,并在文件的每一行快速调用一个函数

Java 处理一个大文件,并在文件的每一行快速调用一个函数,java,performance,io,java-stream,Java,Performance,Io,Java Stream,我有一个大约10.000.000行文本的文件(是的,我有足够的内存)。 现在,我需要一个包含文件每一行的MyClass(构造函数是MyClass(String s))的列表 List<MyClass> help = Files.lines(Paths.get(s)) .parallel() .map(MyClass::new) .

我有一个大约10.000.000行文本的文件(是的,我有足够的内存)。 现在,我需要一个包含文件每一行的
MyClass
(构造函数是
MyClass(String s)
)的列表

List<MyClass> help = Files.lines(Paths.get(s))
                          .parallel()
                          .map(MyClass::new)
                          .collect(Collectors.toList());
List help=Files.line(path.get)
.parallel()
.map(MyClass::新建)
.collect(Collectors.toList());

但这需要几年的时间才能取得进展。关于如何加快这个问题,有什么想法吗?

首先,从以下文档中摘录相关内容:

[…]对于返回的列表的类型、可变性、可序列化性或线程安全性没有任何保证;如果需要对返回的列表进行更多控制,请使用toCollection(供应商)

现在,让我们更深入地看看收藏家的作品;我们发现:

公共静态最终收集器。特性并发

指示此收集器是并发的,这意味着结果容器可以支持与来自多个线程的同一结果容器并发调用的累加器函数

如果并发收集器也不是无序的,则仅当应用于无序数据源时,才应并发计算它

现在,没有任何东西可以保证
Collectors.toList()
返回的收集器是并发的

尽管启动您的新类可能需要花费很多时间,但这里的安全赌注是假定此收集器不是并发的。但幸运的是,我们有一种方法可以使用并发集合,如javadoc中所述。因此,让我们尝试:

.collect(
        Collector.of(CopyOnWriteArrayList::new,
            List::add,
            (o, o2) -> { o.addAll(o2); return o; },
            Function.<List<String>>identity(),
            Collector.Characteristics.CONCURRENT,
            Collector.Characteristics.IDENTITY_FINISH
        )
    )

您可以添加关于您愿意做什么和希望避免什么的信息。您的过程是什么?从外观上看,您只需从每一行创建某个类的新实例。更令人担忧的是,您应该
.close()
您的流:
Files.lines()
是I/O绑定的。@PM77-1的另一个版本更像是initial而不是其他版本。作为一个非常简单的优化,您可以尝试
Arrays.asList(Files.lines(…)…toArray(MyClass[]::new))
而不是
.collector(collector.toList())
。不过,有了这个收集器就好了。Eclipse给了我一个错误,
类型不匹配:无法从对象转换到列表
好吧,嗯,它至少能为您加快速度吗?:pyes它可以加快速度,但也需要大约10分钟…sooo…是的…这个任务怎么可能只使用我的0.7 cpu btw?那么呢你的想法更高一点?例如,你不能用一个.forEach()来代替你的.collect()调用吗?不;我的意思是,真的有必要从一开始就将所有新创建的对象收集到一个集合中吗?你不能用它们来做你需要做的任何事情吗?例如,stream.parallel().map(MyClass:new).forEach(/*对MyClass*/的实例执行某些操作)
final List<MyClass> list;

try (
    final Stream<String> lines = Files.lines(...);
) {
    list = lines.parallel().map(MyClass::new)
        .collect(seeAbove);
}