【问题标题】:Data Structure to store duplicate lines and their count存储重复行及其计数的数据结构
【发布时间】:2015-04-24 06:02:36
【问题描述】:

我正在使用 Java 处理一个非常大的文件(包含数百万条小行。我需要处理的文件总大小约为 200 GB)。我正在寻找存储重复行及其计数的最佳方法。例如,如果我的文件如下:

Chicago
New York
Chicago
LA
Chicago
LA

那我要存储以下信息:

Chicago 3
New York 1
LA 2

我认为最好的方法是HashMap<String, Int>。但是,由于有数百万个值,在处理一条线时:我需要在地图中搜索该线是否已经存在于地图中。如果是,那么我需要将计数增加 1,然后处理下一行。

有没有更有效的方法来做到这一点?

【问题讨论】:

    标签: java data-structures hashmap


    【解决方案1】:
    • 在地图上:

    我需要在地图上搜索该线是否已经存在于地图中。如果是,那么我需要将计数加 1,然后处理下一行。

    有没有更有效的方法来做到这一点?

    实际上,由于HashMaps 的工作方式,检查“该线是否已经存在于地图中”是非常快速的操作(实际上是一个恒定的操作):

    此实现为基本的 操作(get 和 put),假设散列函数分散 桶中的元素。

    • 存档:

    您需要为键(行)存储一个值(计数),这样就无法避免使用类似地图的结构。您还需要检查文件中的每一行,以便了解该行是否已存储/读取。所以你必须一个一个地解析它们

    【讨论】:

    • @作者和任何好奇的人:HashMaps 实际上是 Hash Tables - 这是使用 Hash 函数作为键的类似 map-like 数据结构的通用名称(独立于语言/技术)。因此,如果您想了解更多关于 HashMaps 工作原理的详细信息,请搜索 HT
    【解决方案2】:

    我认为这是实现目标的最有效方式。无需额外搜索,只需读取和递增:

    Integer count = map.get(word);
    map.put(word, count == null ? 1 : ++count);
    

    用 ConcurrentHashMap 做同样的事情不是更快,而是更短的方法:

    m.compute(word, (k, v) -> v == null ? 1 : v + 1);
    

    【讨论】:

    • 抱歉,我没有使用正确的术语。 “搜索”是指使用get() 方法。所以基本上,我正在做的事情是有效率的!
    • 不应该是:map.put(word, count == null ? 1 : ++count)?
    【解决方案3】:

    由于文件很大,ConcurrentHashMap 应该是一个很好的收藏。它将显着减少您的处理(获取/放置)。

    【讨论】:

      【解决方案4】:

      HashMap 还可以,但是你的数据量太大了,建议你用 NoSQL 解决方案,比如 HBase

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-05
        • 1970-01-01
        • 2013-05-31
        • 1970-01-01
        • 2016-03-23
        相关资源
        最近更新 更多