Java中如何用Stream合并BigQuery与DB2的ItemDTO字段?
如何合并来自两个数据库的DTO字段(BigQuery + DB2)
我有一个ItemDTO类,部分字段来自BigQuery,其余来自DB2。尝试用Java Stream合并两个查询结果时,DB2对应的字段始终为null,只保留了BigQuery的字段值。以下是我的代码、数据示例和预期结果,求正确的合并方法。
public static class ItemDTO { String itemNumber; String itemName; int postcode; String location; String price; // getter & setters } List<ItemDTO> bigQueryResults = // BigQuery查询结果 /* BigQuery返回数据: [{ "itemNumber":"101", "itemName":"chair", "postcode":4513, "location":null, "price":null }, { "itemNumber":"102", "itemName":"Table", "postcode":2341, "location":null, "price":null }]*/ List<ItemDTO> db2Results = // DB2查询结果 /* DB2返回数据: [{ "itemNumber":"102", "itemName":null, "postcode":null, "location":"New York", "price":"120" }, { "itemNumber":"101", "itemName":null, "postcode":null, "location":"Amsterdam", "price":"250" }]*/ // 尝试合并两个数据源的结果(以itemNumber为匹配键) List<ItemDTO> resultList = db2Results.stream() .filter(a -> bigQueryResults.stream().anyMatch(item -> item.getItemNumber().equals(a.getItemNumber()))) .collect(Collectors.toList()); /* 预期输出: [{ "itemNumber":"101", "itemName":"chair", "postcode":4513, "location":"Amsterdam", "price":"250" }, { "itemNumber":"102", "itemName":"Table", "postcode":2341, "location":"New York", "price":"120" }]*/ /* 当前实际输出: [{ "itemNumber":"101", "itemName":"chair", "postcode":4513, "location":null, "price":null }, { "itemNumber":"102", "itemName":"Table", "postcode":2341, "location":null, "price":null }]*/
问题分析
当前的Stream操作仅完成了过滤匹配条目的逻辑,完全没有执行字段合并——最终得到的还是BigQuery的原始DTO对象,DB2的字段自然不会被填充。要实现合并,需要以itemNumber为唯一标识,将两个数据源的对应字段整合到同一个DTO中。
解决方案代码
步骤1:将其中一个数据源转为Map(提升查找效率)
先把DB2的结果转成以itemNumber为key的Map,这样后续查找对应条目的时间复杂度从O(n)降到O(1),避免嵌套Stream的低效问题。
步骤2:遍历主数据源并合并字段
以BigQuery的结果为主数据,遍历每个DTO,从Map中取出对应DB2的条目,将非null字段合并进去。
// 将DB2结果转为Map,key为itemNumber Map<String, ItemDTO> db2ItemMap = db2Results.stream() .collect(Collectors.toMap(ItemDTO::getItemNumber, dto -> dto)); // 合并两个数据源的字段 List<ItemDTO> mergedResults = bigQueryResults.stream() .map(bqItem -> { ItemDTO db2Item = db2ItemMap.get(bqItem.getItemNumber()); if (db2Item != null) { // 合并DB2的非null字段到BigQuery的DTO中 if (db2Item.getLocation() != null) { bqItem.setLocation(db2Item.getLocation()); } if (db2Item.getPrice() != null) { bqItem.setPrice(db2Item.getPrice()); } // 如果需要用DB2补全BigQuery的空字段,可添加以下逻辑 // if (bqItem.getItemName() == null && db2Item.getItemName() != null) { // bqItem.setItemName(db2Item.getItemName()); // } } return bqItem; }) .collect(Collectors.toList());
关键说明
- 合并规则自定义:可以根据业务需求调整合并逻辑——比如优先保留BigQuery的字段,仅用DB2补全null值;或者反过来用DB2为主数据,合并BigQuery的字段。
- 空值安全处理:必须先判断
db2Item是否存在,再处理字段,避免空指针异常。 - 方法名校验:确保
ItemDTO的getter/setter方法正确(比如getItemNumber()对应字段itemNumber),避免因方法名错误导致匹配失败。
验证结果
运行上述代码后,合并后的结果将完全符合预期,DB2的location和price字段会正确填充到对应的DTO中。
内容的提问来源于stack exchange,提问作者sharonm
相关产品推荐
相关产品推荐

