Convert JSON String to Java Map with Jackson

In this tutorial, we'll be taking a look at how to convert a JSON String into a Java Map using Jackson, an extremely popular data-binding library for Java.

Specifically, we'll be working with this JSON object:

{
"Task 1" : "In-Progress",
"Task 2" : "Done",
"Task 3" : "Planned"
}

Since we're working with an external library, let's add the required dependency. If you're using Maven, you can add it to your project with:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.3</version>
</dependency>

Or if you're using Gradle, you can add:

implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.11.3'

Convert JSON String to Java Map

For our task status labels, let's define an Enum. We'll have a Map<String, TASK_STATUS> pair, though, you can go with any type here, really:

enum TASK_STATUS {
    In_Progress, Done, Planned
}

Naturally, Jackson's key class is the ObjectMapper class - the main API for object-related data-binding of the library.

Much like you'd map JSON values to other types, to convert JSON contents into a Java Map, you'll use the readValue() method of the ObjectMapper instance, which deserializes it into the provided class reference:

String json = "{\n" +
               "\"Task 1\" : \"In_Progress\",\n" +
               "\"Task 2\" : \"Done\",\n" +
               "\"Task 3\" : \"Planned\"\n" +
               "}";

// ObjectMapper instantiation
ObjectMapper objectMapper = new ObjectMapper();

// Deserialization into a Map
Map<String, TASK_STATUS> result = objectMapper.readValue(json, HashMap.class);
        
// Printing the results
System.out.println(result.entrySet());

We've chucked the json contents into the readValue() method, and since it contains JSON that can be deserialized into a Map, given the key-value pairings, told Jackson to deserialize into a HashMap. Running this code results in:

[Task 2=Done, Task 1=In_Progress, Task 3=Planned]

Now, since HashMaps do not preserve the order of insertion, you might want to use a LinkedHashMap instead, if the order of insertion is important to you:

Map<String, TASK_STATUS> result = objectMapper.readValue(json, LinkedHashMap.class);

This results in:

[Task 1=In_Progress, Task 2=Done, Task 3=Planned]

An alternative to specifying the JavaType directly would be to use the TypeReference class from Jackson:

Map<String, TASK_STATUS> result = objectMapper.readValue(json, 
            new TypeReference<LinkedHashMap>(){});

Now, printing this map will also result in:

[Task 1=In_Progress, Task 2=Done, Task 3=Planned]

Both of these construct an object by calling the exact same deserialization process. So the only difference between these two calls is whether you're making a static (JavaType) or dynamic (TypeReference) reference to the type.