I had a need for having Key/Value pairs in the order of my insertion, so I opted to use LinkedHashMap
over HashMap
. But I need to convert the LinkedHashMap
into a JSON String where the order in the LinkedHashMap
is maintained in the string.
But currently I'm achieving it by:
- First converting the LinkedHashMap into JSON.
Then converting the JSON into a string.
import java.util.LinkedHashMap; import java.util.Map; import org.json.JSONObject; public class cdf { public static void main(String[] args) { Map<String,String > myLinkedHashMap = new LinkedHashMap<String, String>(); myLinkedHashMap.put("1","first"); myLinkedHashMap.put("2","second"); myLinkedHashMap.put("3","third"); JSONObject json = new JSONObject(myLinkedHashMap); System.out.println(json.toString()); } }
The output is:
{"3":"third","2":"second","1":"first"} .
But I want it in the order of insertion of the keys, like this:
{"1":"first","2":"second","3":"third"}
Once I convert the LinkedHashMap
into a JSON it loses it order (it's obvious that JSON doesn't have the notion of order) and hence the string too is out of order. Now, how do I generate a JSON string whose order is same as the LinkedHashMap
?
Gson if your friend. This will print the ordered map into an ordered JSON string.
If you want to preserve insertion order, use a LinkedHashMap
.
I used the latest version of Gson (2.8.5), you can can download it via the following options at the bottom of this post.
import java.util.*;
import com.google.gson.Gson;
public class OrderedJson {
public static void main(String[] args) {
// Create a new ordered map.
Map<String,String> myLinkedHashMap = new LinkedHashMap<String, String>();
// Add items, in-order, to the map.
myLinkedHashMap.put("1", "first");
myLinkedHashMap.put("2", "second");
myLinkedHashMap.put("3", "third");
// Instantiate a new Gson instance.
Gson gson = new Gson();
// Convert the ordered map into an ordered string.
String json = gson.toJson(myLinkedHashMap, LinkedHashMap.class);
// Print ordered string.
System.out.println(json); // {"1":"first","2":"second","3":"third"}
}
}
If you want the items to always be inserted at the right place, use a TreeMap
instead.
import java.util.*;
import com.google.gson.Gson;
public class OrderedJson {
public static void main(String[] args) {
// Create a new ordered map.
Map<String,String> myTreeHashMap = new TreeMap<String, String>();
// Add items, in any order, to the map.
myTreeHashMap.put("3", "third");
myTreeHashMap.put("1", "first");
myTreeHashMap.put("2", "second");
// Instantiate a new Gson instance.
Gson gson = new Gson();
// Convert the ordered map into an ordered string.
String json = gson.toJson(myTreeHashMap, TreeMap.class);
// Print ordered string.
System.out.println(json); // {"1":"first","2":"second","3":"third"}
}
}
Dependency Options
Maven
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
Gradle
compile 'com.google.code.gson:gson:2.8.5'
Or you can visit Maven Central for more download options.
JSONObject
implies use of org.json
library. Don't do that; it is old prototype and there are better options like Jackson and GSON.
With Jackson you would just use:
String json = new ObjectMapper().writeValueAsString(myLinkedHashMap);
and get JSON string with entries in whatever traversal order your Map uses.
JSON not taking insertion order due to linkedhashmap params both are string. Is it fine to change first param as Integer like below mentioned code:
Map<Integer,String > myLinkedHashMap = new LinkedHashMap<>();
myLinkedHashMap.put(1,"first");
myLinkedHashMap.put(2,"second");
myLinkedHashMap.put(3,"third");
System.out.println(myLinkedHashMap);
JSONObject json = new JSONObject(myLinkedHashMap);
System.out.println(json.toString());
To sort alphabetically, here is the proper way with Jackson 2.*:
Map<String, String> myLinkedHashMap = new LinkedHashMap<String, String>();
myLinkedHashMap.put("1", "first");
myLinkedHashMap.put("2", "second");
myLinkedHashMap.put("3", "third");
ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
try {
System.out.println(mapper.writeValueAsString(myLinkedHashMap));
//prints {"1":"first","2":"second","3":"third"}
} catch (JsonProcessingException e) {
e.printStackTrace();
}
I ran into the same problem. I had to use this particular library, and the first element must be with the key "$type". Here is my decision:
import org.json.JSONObject;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
class TypedJSONObject extends JSONObject {
private static final String KEY = "$type";
@Override
public Set<Map.Entry<String, Object>> entrySet() {
Set<Map.Entry<String, Object>> superSet = super.entrySet();
Set<Map.Entry<String, Object>> returnSet = new LinkedHashSet<>();
HashMap<String, Object> map = new HashMap<>();
for (Map.Entry<String, Object> entry : superSet) {
if (entry.getKey().equals(KEY)) {
map.put(KEY, entry.getValue());
break;
}
}
Set<Map.Entry<String, Object>> entries = map.entrySet();
returnSet.addAll(entries);
returnSet.addAll(superSet);
return returnSet;
}
}
As you see I overrite method entrySet, that used in method toString
Create JsonArray for Ordered Pair...
JSONArray orderedJson=new JSONArray();
Iterator iterator= ;
while (iterator.hasNext()) {
Map.Entry me = (Map.Entry)iteratornext();
System.out.print(me.getKey() + ": ");
System.out.println(me.getValue());
JSONObject tmpJson=new JSONObject ();
tmpJson.put(me.getKey(),me.getValue());//add key/value to tmpjson
orderedJson.add(tmpJson);//add tmpjson to orderedJson
}
来源:https://stackoverflow.com/questions/29491281/building-ordered-json-string-from-linkedhashmap