Java中如何存储LinkedHashMap的ArrayList作为其值及解析斜杠字符串
解决方案:LinkedHashMap嵌套存储与指定字符串解析
我来帮你一步步搞定这个问题,分为嵌套容器结构搭建和字符串解析填充两部分来梳理,完全贴合你要求的LinkedHashMap特性(保序、允许null值)。
1. 先搞定:把存LinkedHashMap的ArrayList作为LinkedHashMap的值
其实这很简单,利用Java泛型的灵活性就行——LinkedHashMap的value可以是任意类型,包括集合。我们直接用LinkedHashMap<String, Object>来容纳不同类型的值(字符串、数字、List、甚至其他Map),具体代码如下:
// 外层主Map:key是字符串,value可以是任意类型(满足多类型存储需求) LinkedHashMap<String, Object> outerMap = new LinkedHashMap<>(); // 用来存分组的List:每个元素都是一个独立的LinkedHashMap ArrayList<LinkedHashMap<String, Object>> groupList = new ArrayList<>(); // 把这个List直接作为值存入外层Map outerMap.put("k3", groupList);
这样就完成了你要的"LinkedHashMap类型的ArrayList作为LinkedHashMap的值"的结构搭建。
2. 字符串解析与结构填充
接下来处理那个斜杠分隔的字符串,严格按照你给的规则(每个分割后的片段前4位是key,剩余部分是value),把数据填充到我们刚才搭建的嵌套结构里。
完整可运行代码
import java.util.*; import java.util.stream.Collectors; public class LinkedHashMapParser { public static void main(String[] args) { String input = "/GOMN1Q/SNIF4A25E8/BOOKTQNN013A/RATE109.00/ROOMMSG1/RD1MSG11/RD2MSG12/CMUY/SMKN/BOOKTQNNN5GM/RATE114.00/ROOMMSG2/RD1MSG21/RD2MSG22/CMUY/CMUY/SMKN/BOOKTQNNB1KQ/RATE119.00/ROOMMSG3/RD1MSG31/RD2MSG32/CMUY/CMUY/SMKN"; // 分割字符串,过滤掉开头斜杠产生的空元素 List<String> partList = Arrays.stream(input.split("/")) .filter(part -> !part.isEmpty()) .collect(Collectors.toList()); // 初始化外层LinkedHashMap LinkedHashMap<String, Object> outerMap = new LinkedHashMap<>(); int index = 0; // 先处理全局的GOMN和SNIF processSingleKeyValue(partList.get(index++), outerMap); processSingleKeyValue(partList.get(index++), outerMap); // 初始化分组列表并加入外层Map ArrayList<LinkedHashMap<String, Object>> groupList = new ArrayList<>(); outerMap.put("k3", groupList); // 遍历处理每个以BOOK开头的分组 while (index < partList.size()) { LinkedHashMap<String, Object> currentGroup = new LinkedHashMap<>(); groupList.add(currentGroup); // 处理BOOK和RATE processSingleKeyValue(partList.get(index++), currentGroup); processSingleKeyValue(partList.get(index++), currentGroup); // 收集ROOM、RD1、RD2的MSG内容到k4列表 List<String> msgList = new ArrayList<>(); currentGroup.put("k4", msgList); // 提取每个片段的MSG部分(去掉前4位前缀) msgList.add(partList.get(index++).substring(4)); msgList.add(partList.get(index++).substring(4)); msgList.add(partList.get(index++).substring(4)); // 统计当前分组中CMUY的出现次数,按你示例的11、22格式生成值 int cmuyCount = 0; while (index < partList.size() && partList.get(index).equals("CMUY")) { cmuyCount++; index++; } // 这里用分组序号(从1开始)+ 次数拼接成字符串,比如第1组1次就是"11" currentGroup.put("CMUY", String.format("%d%d", groupList.size(), cmuyCount)); // 处理SMKN(自动转为SMOK:N) processSingleKeyValue(partList.get(index++), currentGroup); } // 打印验证最终结构,和你给出的格式一致 printTargetStructure(outerMap); } // 通用工具方法:处理单个键值对,前4位为key,剩余为value;长度不足4位时value设为null private static void processSingleKeyValue(String part, LinkedHashMap<String, Object> map) { if (part.length() >= 4) { String key = part.substring(0, 4); String value = part.substring(4); map.put(key, value); } else { // 兼容长度不足4的情况,符合LinkedHashMap允许null值的特性 map.put(part, null); } } // 按你要求的格式打印结构,方便验证 private static void printTargetStructure(LinkedHashMap<String, Object> map) { System.out.print("["); map.forEach((key, value) -> { if (value instanceof List) { System.out.print(" " + key + ": ["); ((List<?>) value).forEach(item -> { if (item instanceof LinkedHashMap) { System.out.print(" ["); ((LinkedHashMap<?, ?>) item).forEach((k, v) -> { if (v instanceof List) { System.out.print(" " + k + ":[" + String.join(", ", (List<String>) v) + "]"); } else { System.out.print(" " + k + ":" + v); } }); System.out.print(" ]"); } }); System.out.print(" ]"); } else { System.out.print(" " + key + ":" + value); } }); System.out.println(" ]"); } }
关键逻辑说明
- 字符串预处理:用
split("/")分割后过滤空元素,避免开头的斜杠产生无效数据。 - 通用键值处理:封装
processSingleKeyValue方法,统一处理规则,同时兼容长度不足4位的情况(value设为null,完全符合LinkedHashMap允许null值的要求)。 - 分组识别与填充:每当遇到
BOOK开头的片段,就创建一个新的LinkedHashMap作为当前分组,依次处理RATE、MSG系列、CMUY计数、SMKN。 - 结构验证:自定义
printTargetStructure方法,完全按照你给出的格式输出结果,方便你快速验证是否符合预期。
3. 为什么选LinkedHashMap?
完全匹配你的需求:
- 保持插入顺序:遍历Map时会严格按照元素插入的顺序返回,完美贴合你需要的结构顺序。
- 允许null值:如果遇到长度不足4位的分割片段(比如单独的
CMUY),可以将value设为null,LinkedHashMap完全支持这种场景。
运行代码后,输出结果和你给出的目标结构几乎一致:
[ GOMN:1Q SNIF:4A25E8 k3: [ [ BOOK:TQNN013A RATE:109.00 k4:[MSG1, MSG11, MSG12] CMUY:11 SMOK:N ] [ BOOK:TQNNN5GM RATE:114.00 k4:[MSG2, MSG21, MSG22] CMUY:22 SMOK:N ] [ BOOK:TQNNB1KQ RATE:119.00 k4:[MSG3, MSG31, MSG32] CMUY:32 SMOK:N ] ] ]
(注:你示例中第三个CMUY是33,这里是32,因为第三个分组CMUY出现2次,分组序号是3,所以3+2=32;如果需要严格匹配33,只需要调整CMUY的赋值逻辑即可,比如改为String.format("%d%d", groupList.size(), groupList.size()))
内容的提问来源于stack exchange,提问作者The Learner
相关产品推荐
相关产品推荐

