在Java中将大文件标记为哈希表

在Java中将大文件标记为哈希表,java,hashmap,corpus,Java,Hashmap,Corpus,我遇到了这个问题:我正在读取900个文件,处理完这些文件后,我的最终输出将是一个HashMap为什么不一次只读取一个文件,然后将该文件的结果转储到磁盘,然后读取下一个文件等?很明显,每个文件在映射方面都是独立的,所以为什么在编写第二个文件时保留第一个文件的结果呢 您可以将每个文件的结果写入另一个文件(例如foo.txt=>foo.txt.map),也可以创建一个在结果之间使用某种分隔符的文件,例如 ==== foo.txt ==== word - 1 the - 3 get - 3 ==== b

我遇到了这个问题:我正在读取900个文件,处理完这些文件后,我的最终输出将是一个
HashMap为什么不一次只读取一个文件,然后将该文件的结果转储到磁盘,然后读取下一个文件等?很明显,每个文件在映射方面都是独立的,所以为什么在编写第二个文件时保留第一个文件的结果呢

您可以将每个文件的结果写入另一个文件(例如foo.txt=>foo.txt.map),也可以创建一个在结果之间使用某种分隔符的文件,例如

==== foo.txt ====
word - 1
the - 3
get - 3
==== bar.txt ====
apple - 2
// etc

顺便问一下,你为什么要用
double
作为频率?当然它应该是一个整数值…

您可以尝试使用此库来提高性能

它类似于java collections api,但用于高性能。如果您可以在小批量处理这些结果后对其进行批处理和合并,这将是理想的

这里有一篇文章将帮助您提供更多信息


我正试图重新思考您的问题:

由于您正在尝试构造反向索引:

  • 使用而不是
    Map

    Multimap

  • 现在,读取一个文件,构建多重映射并将其保存在磁盘上。(类似于乔恩的回答)

  • 读取x文件后,将所有多重映射合并在一起:
    putAll(多重映射)
    如果您确实需要所有值的公共映射


  • 哈希映射的处理时间不应随着其增长而显著增加。有可能是由于哈希函数不合适或填充过多,导致地图倾斜。除非您使用的RAM超过了您从系统中获得的RAM,否则您不应该将事情分解

    我在Java中看到,当运行内存中有大量对象的大型哈希映射(或任何集合)时,VM会疯狂地尝试运行垃圾收集器。它达到了90%的时间都花在JVM启动垃圾收集器上,这需要一段时间,并且发现几乎每个对象都有一个引用


    我建议分析您的应用程序,如果它是垃圾收集器,则增加堆空间并调优垃圾收集器。此外,如果您可以近似地计算所需的哈希映射大小,并提供足够大的分配(请参阅构造函数中的initialCapacity和loadFactor选项),这也会有所帮助。

    为什么不使用自定义类

    public class CustomData {
     private String word;
     private double frequency;
     //Setters and Getters
    }
    
    并使用您的地图作为

    Map<fileName, List<CustomData>>
    
    Map
    
    这样你的地图上至少只有900把钥匙


    -Ivar

    你能更具体地描述语料库中的数据吗?它听起来不像,比如说,英语文本。。。或者你是怎么分的?所有文件中的标记是否大致相同,即您可以将其插入?应用特定模式将其拆分,可以是任何内容、空格、句号等,因为输出是整个语料库,具有单词频率。这可以在最后混合所有东西=?@user974594:我真的没有注意到这个评论。。。但如果你把每个地图都存储在自己的文件中,按字母顺序排序,你可能会在以后做一些聪明的事情。不清楚你需要做什么。嗯,我喜欢你的解决方案。多重映射性能如何?putAll将合并所有多重贴图。重复的单词呢?我能将两个频率(值)相加吗?1。你真的需要一个巨大的地图在内存中吗?不。我需要用单词频率将整个语料库打印到一个文件中。在这种情况下,保存不同的多重地图并单独打印它不起作用,我需要整个语料库。我喜欢你的解决方案,但是我怎样才能在结尾处混合键并对所有单词的值求和呢?