首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将带有对象值的Map转换为适当的类型?

如何将带有对象值的Map转换为适当的类型?
EN

Stack Overflow用户
提问于 2020-03-18 19:12:50
回答 1查看 148关注 0票数 2

我正在进行一个项目,在那里我需要接受一个名为propertiesMap<String, Object>类型的地图。这个Map中可能会有许多不同的键,但我只关心一个:xpathxpath可以有三种不同类型的值:

字符串,如{"xpath": "path/to/xml/tag"}

  • A列表的xpath,例如:{"xpath": ["path/to/xml/tag1", "tag2", "path/tag3"}

  • A Map<String, Map<String, Boolean>>,例如:

代码语言:javascript
运行
复制
{
  "xpath":
  {
    "path/to/xml":
    {
      "setting1?": true,
      "setting2?": true
    },
    "path/tag2":
    {
      "setting1?": false,
      "setting2": true
    },
    "path/to/tag3": null
  }
}

现在我有三个变量:String xpath, Set<String> xpaths, Map<String, Map<String, boolean> xpathMap。我有一个函数,它应该尝试映射properties映射中的properties键的值,它看起来如下:

代码语言:javascript
运行
复制
private void decideXPathType(Map<String, Object> properties)
    {
        Object propertiesXPath = properties.get("xpath");

        if (propertiesXPath instanceof String)
        {
            this.xpath = (String) propertiesXPath;
        } else if (propertiesXPath instanceof List)
        {
            this.xpaths = new HashSet<String>((List) propertiesXPath);
        } else if (propertiesXPath instanceof Map)
        {
            for (Object key : ((Map) propertiesXPath).keySet())
            {
                Map<String, Boolean> value = (Map<String, Boolean>) ((Map) propertiesXPath).get(key);
                this.xpathMap.put((String) key, value);
            }
        } else
        {
            throw new IllegalArgumentException("the xpath value is neither String, List, or Map<String, Boolean>");
        }
    }

但是这个功能看起来很糟糕--有那么多的演员,等等--虽然它很好用,但它看起来太乱了,我想有些事情可能会出错……有什么办法能让这个更干净吗?

编辑:更多细节

properties映射最初是从服务中接收到的json JsonNode requestBody。使用ObjectMapper,我创建一个properties映射如下:

代码语言:javascript
运行
复制
Map<String, Object> properties = new ObjectMapper().convertValue(new ObjectMapper().readTree(requestBody), new TypeReference<Map<String, Object>>(){});

如果我收到一个json字符串,它是我给出的xpathMap示例的值,则得到如下所示的内容:

希望这些信息能帮上忙?

EN

回答 1

Stack Overflow用户

发布于 2020-03-18 19:59:55

在JSON中,对这些不同类型的值使用不同的键:StringListMap。反序列化地图:

代码语言:javascript
运行
复制
@Test
public void test0() throws IOException {
    ObjectMapper om = new ObjectMapper();

    InputStream inputStream = getClass().getClassLoader().getResourceAsStream("xpath-object.json");
    JsonNode jsonNode = om.readTree(inputStream);

    Map<String, Map<String, Boolean>> value = om.readValue(jsonNode.get("xpath").toString(), Map.class);
    // prints {path/to/xml={setting1?=true, setting2?=true}, path/to/tag3=null, path/tag2={setting1?=false, setting2=true}}
    System.out.println(value);
}

如果您需要使用第三方JSON,可以使用以下方法:

代码语言:javascript
运行
复制
@Test
public void test() throws IOException {
    testThemAll("xpath-scalar.json");
    testThemAll("xpath-array.json");
    testThemAll("xpath-object.json");
    // prints: 
    // path/to/xml/tag
    // [path/to/xml/tag1, tag2, path/tag3]
    // {path/to/xml={setting1?=true, setting2?=true}, path/to/tag3=null, path/tag2={setting1?=false, setting2=true}}
}

private void testThemAll(String fileName) throws IOException {
    ObjectMapper om = new ObjectMapper();

    InputStream inputStream = getClass().getClassLoader().getResourceAsStream(fileName);
    JsonNode jsonNode = om.readTree(inputStream).get("xpath");

    if (jsonNode.isValueNode())
        System.out.println(jsonNode.asText());
    else if (jsonNode.isArray()) {
        System.out.println(om.readValue(jsonNode.toString(), List.class));
    } else if (jsonNode.isObject()) {
        Map<String, Map<String, Boolean>> value = om.readValue(jsonNode.toString(), Map.class);
        System.out.println(value);
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60746104

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档