28

As the code below:

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

    }

}

The output is:

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

Is it possible to make the key of the map be exact data but not object's address only? How?

Sam YC
  • 10,725
  • 19
  • 102
  • 158
  • I had the same problem a few days back and found that the key cannot be a pojo for jackson to successfully serialize/deserialize the map. – Shankhoneer Chakrovarty Jul 24 '12 at 10:21
  • @ShankhoneerChakrovarty yes, it must be careful when I want to serialize a complicated object because possibly it contains a map structure with objects as the key! What a trouble! – Sam YC Jul 24 '12 at 12:20

4 Answers4

43

Can we make object as key in map when using JSON?

Strictly, no. The JSON map data structure is a JSON object data structure, which is a collection of name/value pairs, where the element names must be strings. Thus, though it's reasonable to perceive and bind to the JSON object as a map, the JSON map keys must also be strings -- again, because a JSON map is a JSON object. The specification of the JSON object (map) structure is available at http://www.json.org.

Is it possible to make the key of the map be exact data but not object's address only? How?

Costi correctly described the behavior of the default map key serializer of Jackson, which just calls the toString() method of the Java map key. Instead of modifying the toString() method to return a JSON-friendly representation of the map key, it's also possible and reasonably simple to implement custom map key serialization with Jackson. One example of doing so is available at Serializing Map<Date, String> with Jackson.

Community
  • 1
  • 1
Programmer Bruce
  • 64,977
  • 7
  • 99
  • 97
3

The "address" that you see printed is simply what your toString() method returns.

Disregarding the JSON marshaling for now In order for your code to work, you need to implement: equals(), hashCode() and toString() within your InnerPerson class. If you return the name property in toString(), that will become the key in your JSON representation.

But without proper implementations for equals() and hashCode(), you cannot make proper use of a HashMap.

Costi Ciudatu
  • 37,042
  • 7
  • 56
  • 92
2

In addition to existing correct answers, you can also add custom key serializers and key deserializers using Module interface (usually with SimpleModule). This allows you to externally define serialization and deserialization of keys. Either way, keys in JSON must be Strings, like others have pointed out.

StaxMan
  • 113,358
  • 34
  • 211
  • 239
1

It is possible with Gson library.

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

Jagadesh
  • 29
  • 1
  • the Gson solution above will return a json as list not a map. I fixed my problem by finding another way than returning an object as key – user666 Jul 15 '19 at 08:25