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

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(" ]");
    }
}

关键逻辑说明

  1. 字符串预处理:用split("/")分割后过滤空元素,避免开头的斜杠产生无效数据。
  2. 通用键值处理:封装processSingleKeyValue方法,统一处理规则,同时兼容长度不足4位的情况(value设为null,完全符合LinkedHashMap允许null值的要求)。
  3. 分组识别与填充:每当遇到BOOK开头的片段,就创建一个新的LinkedHashMap作为当前分组,依次处理RATE、MSG系列、CMUY计数、SMKN。
  4. 结构验证:自定义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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:59:25