guava 的 table 本质是二维结构,不支持原生三维索引;所谓“三维”需通过嵌套实现,如 table,将第三维藏入值类型,或改用 map 组合、triple 键等替代方案。

Guava 的 Table<r c v></r> 本身是二维结构,不是原生三维表格——它只支持“行键 + 列键 → 值”这一层映射。所谓“三维”,实际是通过嵌套方式模拟出来的,核心思路是让 V 类型本身再是一个 Table 或其他集合。
明确 Table 的二维本质
Table<r c v></r> 中的 R(行)、C(列)共同构成唯一坐标,V 是该坐标的值。它不直接支持“行+列+页”这种三键索引。如果你看到“三维 Table”,那一定是人为构造的嵌套结构,比如:Table<string string table integer>></string> —— 表示:日期(R) × 区域(C) → 指标名到数值的子表。
用嵌套 Table 实现三维语义
把第三维“藏进值类型”是最常用、最清晰的做法:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 定义外层 Table:例如
Table<string string table double>></string>,代表“时间 × 地点 → (指标名 → 数值)” - 每次插入前先创建子 Table:
Table<string double> metrics = HashBasedTable.create(); metrics.put("revenue", 1200.5); metrics.put("cost", 800.0);</string> - 再存入外层:
multiDimTable.put("2026-07", "Shanghai", metrics); - 读取时分两步:
Table<string double> shMetrics = multiDimTable.get("2026-07", "Shanghai"); Double rev = shMetrics.get("revenue");</string>
替代方案:用 Map 组合更灵活
如果第三维逻辑复杂(如需要动态增删、支持多种类型值),纯嵌套 Table 可能不够直观。这时可考虑:
-
Table<string string map object>></string>:用 Map 承载任意指标键值对 -
Map<triple c d>, V></triple>+ Guava 的Triple(需自行定义或用ImmutableTriple等) - 封装成专用类,例如
TimeSeriesTable<date region metric value></date>,内部用Table<date region map value>></date>实现
注意事项和常见坑
使用嵌套 Table 时要注意几点:
- 子 Table 必须显式创建,不能靠
get()返回 null 后直接调用put()—— 会 NPE - 修改子 Table 的内容会反映到外层(因为是引用),但替换整个子 Table(
put()新对象)不会影响旧引用 - 遍历三层数据需嵌套调用:
outerTable.cellSet().forEach(cell → { Table,?> inner = cell.getValue(); inner.cellSet().forEach(...)}); - 性能上,嵌套越深,内存开销和 GC 压力越大;高密度数据建议改用
ArrayTable或数据库
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










