当前位置:首页 > 技术 > 正文内容

使用Guava Table实现多维数据建模

访客 技术 2026年6月1日 1

在处理复杂业务场景时,常常需要对具有多个分类维度的数据进行组织和查询。虽然 Guava 的 Table 接口本质上是一个二维结构(由行键和列键共同定位值),但通过结合嵌套集合或层级映射的方式,我们可以有效模拟出三维甚至更高维度的数据模型。

利用嵌套表构建三维结构

一种常见的扩展方式是将 Table 的值类型设为另一个 TableMap,从而形成层次化索引。例如,在分析销售数据时,可以将"时间"作为外层行键,"区域"作为列键,而每个单元格存储一个包含"指标-数值"映射的内层表。

import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import org.junit.jupiter.api.Test;

import java.util.Map;

public class ThreeDimensionalDataModelTest {

    @Test
    public void buildThreeLevelIndex() {
        // 外层表:日期 → 区域 → (指标 → 数值)
        Table<String, String, Table<String, Integer>> timeRegionMetricTable = HashBasedTable.create();

        // 构造北方区域的数据
        Table<String, Integer> northMetrics = HashBasedTable.create();
        northMetrics.put("Revenue", 9800);
        northMetrics.put("Cost", 4200);
        northMetrics.put("Orders", 156);

        // 构造南方区域的数据
        Table<String, Integer> southMetrics = HashBasedTable.create();
        southMetrics.put("Revenue", 8700);
        southMetrics.put("Cost", 3800);
        southMetrics.put("Orders", 134);

        // 填入外层表
        timeRegionMetricTable.put("2024-11-15", "North", northMetrics);
        timeRegionMetricTable.put("2024-11-15", "South", southMetrics);

        // 查询指定维度组合的值
        Table<String, Integer> targetData = timeRegionMetricTable.get("2024-11-15", "North");
        Integer revenue = targetData.get("Revenue");
        System.out.println("North region revenue on 2024-11-15: " + revenue); // 输出: 9800
    }
}

上述代码中,我们通过两层 Table 实现了三个逻辑维度的索引路径:date → region → metric → value。这种结构适合固定维度顺序且访问模式明确的场景。

遍历多级数据集

当需要扫描全部记录时,可以通过逐层迭代完成。以下示例展示了如何遍历所有日期、区域及其对应的各项指标。

@Test
public void traverseHierarchicalData() {
    Table<String, String, Table<String, Integer>> dataTable = HashBasedTable.create();

    Table<String, Integer> data1 = HashBasedTable.create();
    data1.put("Revenue", 7500);
    data1.put("Profit", 2100);
    dataTable.put("2024-11-10", "East", data1);

    Table<String, Integer> data2 = HashBasedTable.create();
    data2.put("Revenue", 6800);
    data2.put("Profit", 1950);
    dataTable.put("2024-11-10", "West", data2);

    // 多重循环访问完整数据集
    for (Map.Entry<String, Map<String, Table<String, Integer>>> rowEntry : dataTable.rowMap().entrySet()) {
        String date = rowEntry.getKey();
        System.out.println("Processing date: " + date);

        for (Map.Entry<String, Table<String, Integer>> colEntry : rowEntry.getValue().entrySet()) {
            String region = colEntry.getKey();
            System.out.println("  Region: " + region);

            Table<String, Integer> metrics = colEntry.getValue();
            for (Map.Entry<String, Integer> metricEntry : metrics.cellSet()) {
                System.out.printf("    %s: %d%n", metricEntry.getRowKey(), metricEntry.getValue());
            }
        }
    }
}

该方法利用 rowMap() 获取按行组织的视图,并进一步展开每一项的列与内部数据,实现完整的深度遍历。

扩展至四维及以上结构

若需支持四个或更多维度(如年份、月份、地区、产品类别),可引入标准 Map 作为顶层容器,其值指向一个二维 Table,再嵌套另一层映射结构。

@Test
public void fourDimensionModel() {
    // 四维模型:Year → Month → (Region × Metric → Value)
    java.util.Map<String, Table<String, String, Table<String, Integer>>> yearSlice =
            new java.util.HashMap<>();

    // 初始化某月数据
    Table<String, Integer> monthlyMetrics = HashBasedTable.create();
    monthlyMetrics.put("Sales", 22000);
    monthlyMetrics.put("Returns", 800);

    Table<String, String, Table<String, Integer>> monthTable = HashBasedTable.create();
    monthTable.put("North", "Q4", monthlyMetrics);

    yearSlice.put("2024", monthTable);

    // 查询:2024年北区第四季度的销售额
    Table<String, Integer> q4Data = yearSlice.get("2024").get("North", "Q4");
    Integer sales = q4Data.get("Sales");
    System.out.println("2024 Q4 North Sales: " + sales); // 输出: 22000
}

这种方式虽牺牲了一定的统一性,但极大增强了灵活性,适用于维度动态变化或多层级聚合分析的应用。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。