4

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;
Tom McClure
  • 6,699
  • 1
  • 21
  • 21
Rafael Carrillo
  • 2,772
  • 9
  • 43
  • 64

1 Answers1

16

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 {...}.

helmy
  • 9,068
  • 3
  • 32
  • 31
Tom McClure
  • 6,699
  • 1
  • 21
  • 21
  • Note that there's actually a typo in the ContainerFactory method name for createArrayContainer(). "create" is missing the "e" at the end, so for your anonymous inner class the method should be named `creatArrayContainer()`. This is true for json-simple 1.1 and 1.1.1 – helmy Nov 03 '17 at 22:35