How to parse from JSON to Map with Json-Simple and retain key order

13.8k Views Asked by At

I'm using Json-Simple to write a config file using JSon-Simple lib, but I'm having problems converting the json string to map.

Debugging I have found that parse method returns an object that is a Map! but when I try to cast directly to a LinkedMap I get a ClassCastException:

 String json = aceptaDefault();
 JSONParser parser = new JSONParser();
 Object obj = parser.parse(json);  
 LinkedHashMap map = (LinkedHashMap)obj;
1

There are 1 best solutions below

1
On BEST ANSWER

You can't just cast a Map to a LinkedHashMap unless you know the underlying object is actually a LinkedHashMap (or is an instance of a class that extends LinkedHashMap).

JSON-Simple by default probably uses a HashMap under the hood and intentionally does not preserve the order of the keys in the original JSON. Apparently this decision was for performance reasons.

But, you're in luck! There is a way around this - it turns out, you can supply a custom ContainerFactory to the parser when decoding (parsing) the JSON.

http://code.google.com/p/json-simple/wiki/DecodingExamples#Example_4_-_Container_factory

String json = aceptaDefault();
JSONParser parser = new JSONParser();

ContainerFactory orderedKeyFactory = new ContainerFactory()
{
    public List creatArrayContainer() {
      return new LinkedList();
    }

    public Map createObjectContainer() {
      return new LinkedHashMap();
    }

};

Object obj = parser.parse(json,orderedKeyFactory);  
LinkedHashMap map = (LinkedHashMap)obj;

This should preserve the key order in the original JSON.

If you don't care about the key order, you don't need a LinkedHashMap and you probably just meant to do this:

String json = aceptaDefault();
JSONParser parser = new JSONParser();
Object obj = parser.parse(json);  
Map map = (Map)obj;

You still might get a ClassCastException, but only if the json is a list [...] and not an object {...}.