26

如下代码:

public class Main {

    public class innerPerson{
        private String name;
        public String getName(){
            return name;
        }
    }


    public static void main(String[] args){
        ObjectMapper om = new ObjectMapper();

        Map<innerPerson, String> map = new HashMap<innerPerson,String>();

        innerPerson one = new Main().new innerPerson();
        one.name = "david";

        innerPerson two = new Main().new innerPerson();
        two.name = "saa";

        innerPerson three = new Main().new innerPerson();
        three.name = "yyy";

        map.put(one, "david");
        map.put(two, "11");
        map.put(three, "true");



        try {
            String ans = om.writeValueAsString(map);

            System.out.println(ans);


        } catch (JsonGenerationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JsonMappingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

输出是:

{"Main$innerPerson@12d15a9":"david","Main$innerPerson@10a3b24":"true","Main$innerPerson@e91f5d":"11"}

是否可以使地图的键是精确的数据而不是对象的地址?如何?

4

4 回答 4

40

使用 JSON 时,我们可以将对象作为 map 中的键吗?

严格来说,没有。JSON map数据结构是一个 JSON对象数据结构,它是一个名称/值对的集合,其中元素名称必须是字符串。因此,尽管将 JSON 对象作为映射来感知和绑定是合理的,但 JSON 映射键也必须是字符串——同样,因为 JSON 映射是 JSON 对象。JSON 对象(映射)结构的规范可在http://www.json.org获得。

是否可以使地图的键是精确的数据而不是对象的地址?如何?

Costi 正确地描述了 Jackson 的默认映射键序列化程序的行为,它只是调用toString()Java 映射键的方法。除了修改toString()方法以返回映射键的 JSON 友好表示形式外,还可以使用 Jackson 实现自定义映射键序列化并且相当简单。Serializing Map<Date, String> with Jackson提供了一个这样做的例子。

于 2012-07-24T15:19:21.833 回答
3

您看到打印的“地址”就是您的toString()方法返回的内容。

现在忽略 JSON 封送处理为了让您的代码正常工作,您需要在您的类中实现:和equals()。如果您在 中返回 name 属性,它将成为您的 JSON 表示中的键。hashCode()toString()InnerPersontoString()

但是如果没有正确实现equals()and hashCode(),就无法正确使用 HashMap。

于 2012-07-24T10:25:38.470 回答
2

除了现有的正确答案之外,您还可以使用 Module 接口(通常使用SimpleModule)添加自定义密钥序列化器和密钥反序列化器。这允许您在外部定义密钥的序列化和反序列化。无论哪种方式,JSON 中的键都必须是字符串,就像其他人指出的那样。

于 2012-07-24T17:08:12.247 回答
1

使用 Gson 库是可能的。

Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create(); gson.toJson(地图);

于 2018-10-29T22:36:28.567 回答