Guava Table嵌套组合实现多维度数据存储
在数据处理中,二维Table可以理解为行列交叉的网格,但实际业务常需要更多维度(如时间+地区+指标)。Guava的Table虽然原生只支持二维,但通过组合其他集合类型,可以灵活模拟出多维结构。
1. 通过Table嵌套构造三维数据
核心思路是将Table的值域扩展为另一个Table,从而获得三维索引能力(例如:日期→区域→指标)。示例代码演示了如何存储和查询时间序列数据:
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import java.util.Map;
public class Demo3DTable {
public void run() {
// 三维Table: 日期 -> 区域 -> 子Table(指标名 -> 值)
Table<String, String, Table<String, Integer>> data = HashBasedTable.create();
// 构造第一组区域数据
Table<String, Integer> northMetrics = HashBasedTable.create();
northMetrics.put("Sales", 1000);
northMetrics.put("Profit", 200);
// 构造第二组区域数据
Table<String, Integer> southMetrics = HashBasedTable.create();
southMetrics.put("Sales", 1200);
southMetrics.put("Profit", 300);
// 填充三维结构
data.put("2024-12-01", "North", northMetrics);
data.put("2024-12-01", "South", southMetrics);
// 查询:2024-12-01的North区域Sales值
Table<String, Integer> northSub = data.get("2024-12-01", "North");
System.out.println("North Sales: " + northSub.get("Sales")); // 输出1000
// 查询:2024-12-01的South区域Profit值
Table<String, Integer> southSub = data.get("2024-12-01", "South");
System.out.println("South Profit: " + southSub.get("Profit")); // 输出300
}
}
这种嵌套方式允许通过三个连续的键(日期、区域、指标名)精确定位到数值,直观地模拟了三维数据表。
2. 多维度遍历与查询
遍历多维数据时,可以逐层深入:先遍历外层Table的行列键,再遍历子Table的内容。以下代码展示了完整的层级访问:
public void traverse3D() {
Table<String, String, Table<String, Integer>> cube = HashBasedTable.create();
// 填充数据
Table<String, Integer> d1 = HashBasedTable.create();
d1.put("Sales", 2000); d1.put("Profit", 500);
Table<String, Integer> d2 = HashBasedTable.create();
d2.put("Sales", 1500); d2.put("Profit", 450);
cube.put("2024-12-01", "North", d1);
cube.put("2024-12-01", "South", d2);
// 遍历所有维度
for (String date : cube.rowKeySet()) {
for (String region : cube.columnKeySet()) {
Table<String, Integer> metrics = cube.get(date, region);
if (metrics != null) {
System.out.printf("Date=%s, Region=%s%n", date, region);
for (Map.Entry<String, Integer> entry : metrics.cellSet()) {
System.out.printf(" %s: %d%n", entry.getKey(), entry.getValue());
}
}
}
}
}
通过cellSet()可以获取子Table中的所有键值对,结合外层键即可得到完整的多维索引。
3. 用Map+Table实现四维结构
当需要四维或更高维度时,可以混合使用Map与Table。例如用外层Map表示年份,内层Table表示月份→区域→指标:
import java.util.HashMap;
import java.util.Map;
public class Demo4D {
public void build4DStructure() {
// 四维:年份 → 月份 → 区域 → 指标值
Map<String, Table<String, String, Table<String, Integer>>> yearData = new HashMap<>();
// 构造第三层:区域 → 指标
Table<String, String, Integer> regionMetric = HashBasedTable.create();
regionMetric.put("Sales", 1500);
regionMetric.put("Profit", 300);
// 构造第二层:月份 → 区域结构
Table<String, String, Table<String, Integer>> monthData = HashBasedTable.create();
monthData.put("January", "North", regionMetric);
// 放入第一层Map
yearData.put("2024", monthData);
// 查询:2024年1月的North区域Sales值
Table<String, String, Table<String, Integer>> jan = yearData.get("2024");
Table<String, Integer> north = jan.get("January", "North");
int sales = north.get("Sales");
System.out.println("2024 January Sales: " + sales); // 输出1500
}
}
通过Map与Table的任意组合,理论上可以构造任意维度的数据容器,但需注意可维护性和性能开销。
小结
Guava Table虽然仅提供二维语义,但通过嵌套和组合其他集合类(Table、Map),可以灵活构建三维甚至四维的数据结构。这种设计在时间序列、多维度报表等场景中非常实用,能够用简洁的代码实现复杂的多维索引逻辑。