You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何合并两个com.google.common.collect.Table并对重复键值求和?

刚好之前处理过类似的Guava Table合并需求,给你两种靠谱的实现方式,完全匹配你要的「相同行键+列键时对应值相加」的需求:

解决方案:合并Guava Table并累加重复键的值

这里假设你使用的是Guava库中的Table接口(比如HashBasedTable实现类),下面分别提供Java 8 Stream的优雅写法,以及更直观的传统迭代写法。

Java 8 Stream 实现方式

我们可以把两个Table的所有单元格(Cell)转成流合并,通过复合键分组后累加值,最后再转回Table结构。这里用AbstractMap.SimpleEntry来封装行键+列键作为复合键,它天然实现了equals和hashCode,可以直接作为Map的键使用。

import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import com.google.common.collect.Table.Cell;

import java.util.AbstractMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class TableMergeStreamExample {
    public static void main(String[] args) {
        // 初始化示例数据
        Table<Long, String, Integer> tableOne = HashBasedTable.create();
        tableOne.put(1L, "Fruits", 20);
        tableOne.put(2L, "Fruits", 30);
        tableOne.put(2L, "Vegetables", 15);
        tableOne.put(3L, "Vegetables", 10);

        Table<Long, String, Integer> tableTwo = HashBasedTable.create();
        tableTwo.put(2L, "Fruits", 10);
        tableTwo.put(2L, "Vegetables", 40);
        tableTwo.put(3L, "Fruits", 15);
        tableTwo.put(4L, "Vegetables", 35);

        // Stream方式合并Table
        Table<Long, String, Integer> sumTable = HashBasedTable.create();

        // 合并两个Table的Cell流,分组累加值
        Map<Map.Entry<Long, String>, Integer> mergedMap = Stream.concat(
                        tableOne.cellSet().stream(),
                        tableTwo.cellSet().stream())
                .collect(Collectors.toMap(
                        // 生成复合键:行键 + 列键
                        cell -> new AbstractMap.SimpleEntry<>(cell.getRowKey(), cell.getColumnKey()),
                        Cell::getValue,
                        // 重复键时执行累加操作
                        Integer::sum));

        // 将Map转换为目标Table
        mergedMap.forEach((key, value) -> sumTable.put(key.getKey(), key.getValue(), value));

        // 打印验证结果
        sumTable.cellSet().forEach(cell ->
                System.out.printf("%s %s %d%n", cell.getRowKey(), cell.getColumnKey(), cell.getValue()));
    }
}

关键步骤说明

  • Stream.concat:把两个Table的单元格流合并成一个统一的流
  • Collectors.toMap:通过复合键分组,遇到重复键时调用Integer::sum完成值的累加
  • 最后遍历合并后的Map,将键值对映射回Table结构

传统迭代实现方式

如果更偏好直观的循环写法,这种方式也很容易理解:先复制第一个Table的所有数据到结果Table,再遍历第二个Table的每个单元格,检查是否存在重复键,存在则累加,不存在则直接插入。

import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;

public class TableMergeTraditionalExample {
    public static void main(String[] args) {
        // 初始化示例数据
        Table<Long, String, Integer> tableOne = HashBasedTable.create();
        tableOne.put(1L, "Fruits", 20);
        tableOne.put(2L, "Fruits", 30);
        tableOne.put(2L, "Vegetables", 15);
        tableOne.put(3L, "Vegetables", 10);

        Table<Long, String, Integer> tableTwo = HashBasedTable.create();
        tableTwo.put(2L, "Fruits", 10);
        tableTwo.put(2L, "Vegetables", 40);
        tableTwo.put(3L, "Fruits", 15);
        tableTwo.put(4L, "Vegetables", 35);

        // 传统方式合并Table
        Table<Long, String, Integer> sumTable = HashBasedTable.create(tableOne); // 先复制tableOne的所有数据

        // 遍历tableTwo的每个单元格
        for (Table.Cell<Long, String, Integer> cell : tableTwo.cellSet()) {
            Long rowKey = cell.getRowKey();
            String columnKey = cell.getColumnKey();
            Integer newValue = cell.getValue();

            // 检查结果Table中是否已有该组合键
            if (sumTable.contains(rowKey, columnKey)) {
                Integer existingValue = sumTable.get(rowKey, columnKey);
                sumTable.put(rowKey, columnKey, existingValue + newValue);
            } else {
                sumTable.put(rowKey, columnKey, newValue);
            }
        }

        // 打印验证结果
        sumTable.cellSet().forEach(cell ->
                System.out.printf("%s %s %d%n", cell.getRowKey(), cell.getColumnKey(), cell.getValue()));
    }
}

关键步骤说明

  • HashBasedTable.create(tableOne):快速复制第一个Table的所有数据到结果表,避免手动遍历插入
  • 遍历第二个Table时,用contains(rowKey, columnKey)判断是否存在重复键,按需执行累加或插入操作

验证结果

两种方式运行后,都会输出符合你预期的结果:

1 Fruits 20
2 Fruits 40
2 Vegetables 55
3 Vegetables 10
3 Fruits 15
4 Vegetables 35

内容的提问来源于stack exchange,提问作者Sunflame

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:00:58