如何访问Java的嵌套哈希图

问题描述

我有一个

Map<String,Object> response = {
    sendResponse = {
        return = {
            SendResponse = {
                txnID = 4fa160ce-638f-4556-9313-afbef543fadd,emailTypeID = 1020261131,txnStatusCode = 1,txnStatusMessage = OK,status = [
                    {   CommunicationStatus = {
                            type = EMAIL,statusCode = 1,statusMessage = OK
                        }
                    }
                ]
            }
        }
    }
}

如何从响应图中提取“ statusMessage”。请告知。

嵌套对象的运行时类型为LinkedHashMap<K,V>,状态类型为ArrayList,其中包含LinkedHashMap<K,V>

例如,我尝试使用get()方法,如下所示,但我面临强制转换警告。 例如:response.get(“ sendResponse”))。get(“ return”))。get(“ SendResponse”)。get(“ status”)。get(0).get(“ CommunicationStatus”)。get(statusMessage) ;

解决方法

需要一点时间。

    Map<String,Object> response = new LinkedHashMap<>(Map.of(
            "sendResponse",new LinkedHashMap<>(Map.of(
                    "return",new LinkedHashMap<>(Map.of(
                            "SendResponse",new LinkedHashMap<>(Map.of(
                                    "txnId","4fa160ce-638f-4556-9313-afbef543fadd","status",new ArrayList<Object>(List.of(
                                            new LinkedHashMap<>(Map.of(
                                                    "CommunicationStatus",new LinkedHashMap<String,Object>(Map.of(
                                                            "type","EMAIL","statusMessage","OK"))))))))))))));
    
    System.out.println(response);
    
    Map<?,?> sendResponse = (Map<?,?>) response.get("sendResponse");
    Map<?,?> returnMap = (Map<?,?>) sendResponse.get("return");
    Map<?,?> sendResponseCapitalS = (Map<?,?>) returnMap.get("SendResponse");
    List<?> status = (List<?>) sendResponseCapitalS.get("status");
    Optional<Map<?,?>> statusEmail = (Optional<Map<?,?>>) status.stream()
            .map(m -> ((Map<?,?>) m).get("CommunicationStatus"))
            .filter(m -> ((Map<?,?>) m).get("type").equals("EMAIL"))
            .findAny();
    Optional<Object> statusMessage = statusEmail.map(m -> m.get("statusMessage"));
    
    statusMessage.ifPresent(System.out::println);

我从您的地图上删除了一些没意思的地方,应该没什么区别。我正在打印为您构建的地图,以检查它是否看起来像您的地图(仅保留了一些内容)。以上代码段的输出是:

{sendResponse={return={SendResponse={txnId=4fa160ce-638f-4556-9313-afbef543fadd,status=[{CommunicationStatus={statusMessage=OK,type=EMAIL}}]}}}}
OK

我正在使用流操作从类型为EMAIL的列表中取出地图。请检查这是否符合您的要求。

编辑:您和我都注意到了警告类型安全性:未经检查,是否从Optional 强制转换为Optional 。我找不到摆脱它的好方法。最终打印输出之前的最后两行的以下变体不显示警告:

    Optional<?> statusEmail = status.stream()
            .map(m -> ((Map<?,?>) m).get("type").equals("EMAIL"))
            .findAny();
    Optional<Object> statusMessage = statusEmail.map(m -> ((Map<?,?>) m).get("statusMessage"));

但是,它们提供的关于statusEmail类型的信息较少,我发现明显的缺点,这就是为什么尽管有警告,我还是选择在上面发布第一个变体。