【问题标题】:Java: Map of maps with identical keysJava:具有相同键的地图映射
【发布时间】:2012-03-22 20:08:33
【问题描述】:

考虑一个具有以下结构的巨大 CSV(为简单起见进行了修改):

ID, NAME,  ADDRESS, PHONE, MAIL
1,  Jon,   UK,      403,  jon@skeet.com
2,  Marc,  UK,      292,  marc@gravel.com
3,  Darin, France,  291,  darin@dimitrov.com
...
(Some million records)

快速获取的自然数据结构是哈希表,其中每个ID 是一个键,NAME, ADDRESS, PHONE, MAIL 是值。我的难题是值的数据结构。

将其存储在HashMap 中,其中每个行标题都是键是浪费空间,因为每行的行标题完全相同。将其存储为数组会丢失每个项目的元数据,因为阅读器

我在考虑两种方法:

  • 重载 Java 的 Hashmap。行标题将被存储一次,每个ID 将与一个字符串数组相关联。 get() 方法将被重载,以便它返回标题行和行中相应字段之间的映射。

  • 创建一个哑类,它使用 getter 和 setter 存储每一行​​的数据(row.getMail()row.getAddress()、...)

就内存效率、类型安全性和速度而言,正确的做法是什么?

【问题讨论】:

    标签: java data-structures dictionary nested hashtable


    【解决方案1】:

    虽然 'dumb' 类是更简洁的方法,但它显然不如 map of maps 方法通用,并且需要特定于 CSV 格式的解析逻辑 - 所以需要权衡取舍。

    您对内存效率的担忧可能不那么重要 - 字符串是interned,因此每个行映射实际上都将具有相同的字符串实例,因此开销仅取决于引用到每个字符串。

    【讨论】:

      【解决方案2】:

      除非您知道自己有问题,否则我不会担心浪费的空间。即你有很多 GB 的数据。

      如果您想知道一种提高效率的方法,您可以使用Map<String, Integer> 的组合来查找键,并为每一行使用Object[]。要按名称查找,请先找到要查找的号码。

      更有效的方法是按列而不是按行存储数据。这更有效,因为您的行数往往多于列数

      Map<String, List> columns = ...
      

      您可以先按名称查找单元格,然后按列表中的条目查找。如果要使用原始类型,可以使用int[]double[]TIntArrayListTDoubleArrayList 来节省内存。 ADDRESS 国家可以是枚举类型。

      除非你有数百万行,否则我会保持简单。

      【讨论】:

      • 我确实有几百万条记录。
      • 在这种情况下,可能值得测试它是否会产生足够的影响(小于我不会打扰的)您可能仍然会发现,虽然它节省了 100 MB,但这仅意味着您的服务器可用内存增加了 100 MB,但保持代码更简单实际上是一个更好的主意。
      【解决方案3】:

      我会选择“哑”类而不是重载集合。

      我不知道类型安全或速度,但我想说您的代码将更具可读性。这些价值观相辅相成;将它们封装在一个对象中以强调这一点。除了获取/设置之外,还有与它们相关的任何行为吗?如果是,那就更好了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-17
        • 1970-01-01
        相关资源
        最近更新 更多