如何在String类型Map中实现重复前缀键的自动递增命名添加?
问题分析与修正方案
需求说明
现有一个从XML提取的Map<String, String>,结构如下:
Map<String,String> map = { BusDetails.BusDetail.DriverID=1, BusDetails.BusDetail.DriverSubID=2, BusDetails1.BusDetail.DriverID=1, BusDetails1.BusDetail.DriverSubID=2 }
需要实现:当添加重复的BusDetails.BusDetail.DriverID类键时,自动生成带递增数字后缀的新键(如BusDetails2.BusDetail.DriverID),保证键的唯一性。
现有代码的问题
- 逻辑冗余混乱:处理重复键时遍历所有前缀列表,多次执行
put操作,会导致重复生成键或错误覆盖。 - 数字递增逻辑错误:仅提取前缀中的数字,但未计算当前最大的后缀值,无法生成正确的递增序号。
- 字符串替换错误:
replaceFirst("\\.", ...)会盲目替换第一个点,若前缀本身带数字(如BusDetails1),会破坏原有结构。
修正后的实现
我们将键的唯一性生成逻辑独立出来,先提取基础前缀,再计算当前最大后缀,最后生成唯一键:
完整代码
private static void extractNodeDataToMap(Node node, String parentNodeName, Map<String, String> outputMap) { if (!(node.getNodeType() == Node.ELEMENT_NODE)) return; // 构建带点分隔的父节点路径 String fullParentPath = parentNodeName.isEmpty() ? "" : parentNodeName + "."; String currentKey = fullParentPath + node.getNodeName(); // 处理叶子节点(仅含文本子节点) if (node.getChildNodes().getLength() <= 1) { String uniqueKey = generateUniqueKey(currentKey, outputMap); outputMap.put(uniqueKey, node.getTextContent().trim()); return; } // 递归处理子节点 for (int i = 0; i < node.getChildNodes().getLength(); i++) { extractNodeDataToMap(node.getChildNodes().item(i), fullParentPath + node.getNodeName(), outputMap); } } // 生成唯一键的工具方法 private static String generateUniqueKey(String originalKey, Map<String, String> existingMap) { // 拆分原始键为基础前缀和后续路径 String[] keyParts = originalKey.split("\\.", 2); String basePrefix = keyParts[0]; String restOfPath = keyParts.length > 1 ? "." + keyParts[1] : ""; // 匹配"基础前缀+数字"的模式(如BusDetails1、BusDetails2) Pattern pattern = Pattern.compile("^" + Pattern.quote(basePrefix) + "(\\d+)$"); int maxSuffix = 0; // 遍历现有键,找出最大的后缀数字 for (String key : existingMap.keySet()) { String keyPrefix = key.split("\\.", 2)[0]; Matcher matcher = pattern.matcher(keyPrefix); if (matcher.find()) { int suffix = Integer.parseInt(matcher.group(1)); if (suffix > maxSuffix) { maxSuffix = suffix; } } } // 原始键不存在则直接返回 if (!existingMap.containsKey(originalKey)) { return originalKey; } // 生成新的唯一键:基础前缀 + (最大后缀+1) + 后续路径 return basePrefix + (maxSuffix + 1) + restOfPath; }
代码说明
- 解耦逻辑:将键的唯一性生成单独抽成
generateUniqueKey方法,避免递归遍历中逻辑嵌套混乱。 - 精准匹配:用正则表达式精准识别带数字后缀的前缀,不会误判其他含数字的键。
- 正确递增:遍历现有键找到当前最大后缀,确保新序号连续递增,不会出现断层。
- 递归优化:简化递归分支逻辑,叶子节点处理更清晰。
测试效果
向现有Map中添加BusDetails.BusDetail.DriverID时,会自动生成BusDetails2.BusDetail.DriverID;再次添加则生成BusDetails3.BusDetail.DriverID,完全符合需求。
内容的提问来源于stack exchange,提问作者piya
相关产品推荐
相关产品推荐

