I'm getting JSON, but it's not in alphabetical order. How to sort json by it's KEY ?
JSON:
{"b":"3","c":"1","a":"4"}
Expected output:
{"a":"4","b":"3","c":"1"}
Please help me to solve this problem. I really appreciate your help! Thanks!
You can use the jackson library.
First add a jackson to the maven dependency.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.7</version>
</dependency>
Then use the code below.
String jsonData = "{\"e\":\"6\",\"f\":\"1\",\"b\":\"3\",\"c\":\"1\",\"a\":\"4\"}";
ObjectMapper om = new ObjectMapper();
om.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
Map<String, Object> map = om.readValue(jsonData, HashMap.class);
String json = om.writeValueAsString(map);
System.out.println(json); // result : {"a":"4","b":"3","c":"1","e":"6","f":"1"}
When I test it, I get output in sorted form.
{"a":"4","b":"3","c":"1","e":"6","f":"1"}
So here is one of solution to sort JSON object by key alphabetically without using external libraries(for Android Studio). The sortedJSON is the one with key sorted alphabetically.
try{
JSONObject jo = new JSONObject();
jo.put("g", "9");
jo.put("t", "8");
jo.put("r", "7");
jo.put("d", "6");
jo.put("c", "5");
jo.put("b", "4");
jo.put("a", "1");
Map<String, String> joToMap = new HashMap<>();
Iterator<String> keysItr = jo.keys();
while (keysItr.hasNext()) {
String key = keysItr.next();
Object value = jo.get(key);
joToMap.put(key, value.toString()); //since value is string so convert toString; depend on your value type
}
Map<String, String> sortedMap = new TreeMap<>(joToMap); //this will auto-sort by key alphabetically
JSONObject sortedJSON = new JSONObject(); //recreate new JSON object for sorted result
for (Map.Entry<String, String> entry : sortedMap.entrySet()) {
sortedJSON.put(entry.getKey(), entry.getValue());
// result will be {"a":"1","b":"4","c":"5","d":"6","g":"9","r":"7","t":"8"}
}
} catch (Exception e){
}
You can use maps for this purpose , then sort the map according to the map key. after that insert it into the JSON object.
In your case declare the map as:
Map<String,Integer> mapName = new HashMap<>();
Related
I have a JSON like this: [{key:key1, value:value1}, {key:key2, value:value2}, ..., {key:keyn, value:valuen}]
and I need a HashMap in Java from that json like: {key1:value1, key2:value2, ..., keyn:valuen}
Is there a simple way to have it converted like this? I'm trying with Jackson but don't know how to specify key and value keywords.
It is very simple:
https://stackoverflow.com/a/24012023/7137584
I would recommend using Jackson library:
import com.fasterxml.jackson.databind.ObjectMapper;
TypeReference<HashMap<String, Object>> typeRef = new TypeReference<>() {};
Map<String, Object> mapping = new ObjectMapper().readValue(jsonStr, typeRef);
The input JSON describes an array/list of map entries where each entry is a POJO:
#Data
class Entry {
private String key;
private String value; // the type of value may be Object
}
Here #Data is a Lombok annotation which provides getters, setters, toString, etc.
So, at first a list of map entries is read, which is converted then to the map:
String json = "[{\"key\":\"key1\", \"value\":\"value1\"}, {\"key\":\"key2\", \"value\":\"value2\"}, {\"key\":\"keyN\", \"value\":\"valueN\"}]";
// step 1: read raw list of entries
List<Entry> input = mapper.readValue(json, new TypeReference<List<Entry>>() {});
// step 2: convert to map
Map<String, String> mapRead = input.stream()
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
System.out.println(mapRead);
Output:
{key1=value1, key2=value2, keyN=valueN}
Here's a solution using the JSON-P api.
import javax.json.*;
var str = "[{\"key\":\"key1\", \"value\":\"value1\"}, {\"key\":\"key2\", \"value\":\"value2\"}, {\"key\":\"keyN\", \"value\":\"valueN\"}]";
JsonReader reader = Json.createReader(new StringReader(str));
JsonArray jarr = reader.readArray();
Map<String,String> map = new HashMap<>();
for(JsonValue jv : jarr) {
JsonObject jo = (JsonObject)jv;
map.put(jo.getString("key"), jo.getString("value") );
}
System.out.println(map);
I am using a JsonReader to convert the String to a JsonArray object.
Each entry of this JsonArray is a JsonObject like {key: keyX, value: valueX}.
I get the values corresponding to 'key' and 'value' and add them to a HashMap using a for loop.
I'm stuck on something silly I'd appriciate some help with,
I'm getting this string via a stringified object in javascript:
{"63F67024-6FE1-D1B9-41D2-61156F11089A":0,"7cc8732e-d532-463e-9b5e-38fe14664b9e":1,"7CC40FFC-7BED-82DF-41C3-78C2BE8CD901":2,"f7344b33-860a-4934-b1f8-044b80a7b894":3,"31f65628-12b1-4363-848d-2bce07b8ac30":4,"7CF2DCA9-7BEC-8566-41A2-4898E5C110BC":5,"7D1C42ED-7BED-82FE-41D2-5045E9F0C13F":6,"D4EC2E5B-D807-2F30-41EA-6A4D9278BE81":7,"91ACF8F7-9516-F12F-41C1-BF57E6F223BE":8,"28d65730-9da0-457b-9d25-0f33628c0e5c":9,"57D44260-6D6D-E0E0-4171-71080149751C":10}
What's the cleanest, simplest way to convert this into an array of objects?
I've started doing something ugly by just removing the unwanted characters and doing something like this:
List<String> list = new ArrayList<String>(Arrays.asList(value.split(",")));
for(String s : list)
System.out.println(s);
But I'm sure there is a cleaner, simpler way ideally with GSON
Your JSON string looks like a simple list of key/value pairs. How about converting it to a Map
public static void jsonToMap(String t) throws JSONException {
HashMap<String, String> map = new HashMap<String, String>();
JSONObject jObject = new JSONObject(t);
Iterator<?> keys = jObject.keys();
while( keys.hasNext() ){
String key = (String)keys.next();
String value = jObject.getString(key);
map.put(key, value);
}
System.out.println("json : "+jObject);
System.out.println("map : "+map);
}
Hope it helps.
jackson having ObjectMapper class which also doing this but it map the with the object and key name and object field name should be same for mapping code will be
import following package
org.codehaus.jackson.map.ObjectMapper;
call will be
ObjectMapper objectMapper = new ObjectMapper();
Yourclass classObj = objectMapper
.readValue(jsonasString,Yourclass.class);
I have a JsonObject e.g
JsonObject jsonObject = {"keyInt":2,"keyString":"val1","id":"0123456"}
Every JsonObject contains a "id" entry, but the number of other key/value pairs is NOT determined, so I want to create create an object with 2 attributes:
class myGenericObject {
Map<String, Object> attributes;
String id;
}
So I want my attributes map to look like this:
"keyInt" -> 4711
"keyStr" -> "val1"
I found this solution
Map<String, Object> attributes = new HashMap<String, Object>();
Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
for(Map.Entry<String,JsonElement> entry : entrySet){
attributes.put(entry.getKey(), jsonObject.get(entry.getKey()));
}
but the values are enclosed by ""
"keyInt" -> "4711"
"keyStr" -> ""val1""
How to get the plain values (4711 and "val1")?
Input data:
{
"id": 0815,
"a": "a string",
"b": 123.4,
"c": {
"a": 1,
"b": true,
"c": ["a", "b", "c"]
}
}
or
{
"id": 4711,
"x": false,
"y": "y?",
}
replace "" with blank.
Map<String, Object> attributes = new HashMap<String, Object>();
Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
for(Map.Entry<String,JsonElement> entry : entrySet){
if (! nonProperties.contains(entry.getKey())) {
properties.put(entry.getKey(), jsonObject.get(entry.getKey()).replace("\"",""));
}
}
How are you creating your JsonObject? Your code works for me. Consider this
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
...
...
...
try{
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("keyInt", 2);
jsonObject.addProperty("keyString", "val1");
jsonObject.addProperty("id", "0123456");
System.out.println("json >>> "+jsonObject);
Map<String, Object> attributes = new HashMap<String, Object>();
Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
for(Map.Entry<String,JsonElement> entry : entrySet){
attributes.put(entry.getKey(), jsonObject.get(entry.getKey()));
}
for(Map.Entry<String,Object> att : attributes.entrySet()){
System.out.println("key >>> "+att.getKey());
System.out.println("val >>> "+att.getValue());
}
}
catch (Exception ex){
System.out.println(ex);
}
And it is working fine. Now I am interested in knowing how you created that JSON of yours?
You can also try this (JSONObject)
import org.json.JSONObject;
...
...
...
try{
JSONObject jsonObject = new JSONObject("{\"keyInt\":2,\"keyString\":\"val1\",\"id\":\"0123456\"}");
System.out.println("JSON :: "+jsonObject.toString());
Iterator<String> it = jsonObject.keys();
while( it.hasNext() ){
String key = it.next();
System.out.println("Key:: !!! >>> "+key);
Object value = jsonObject.get(key);
System.out.println("Value Type "+value.getClass().getName());
}
}
catch (Exception ex){
System.out.println(ex);
}
Just make following changes...
Map<String, Object> attributes = new HashMap<String, Object>();
Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
for(Map.Entry<String,JsonElement> entry : entrySet){
attributes.put(entry.getKey(), jsonObject.get(entry.getKey()).getAsString());
}
"getAsString" will do the magic for u
Your Map values are JsonElements. Whenever you print a JsonElement (e.g. using a debugger) its toString() method will be called - and since a JsonElement has many implementing classes the default toString implementation wraps the value in quotes to ensure correct JSON. To get the value as a normal, unwrapped String, simply call getAsString():
JsonElement elem;
// ...
String value = elem.getAsString();
With your example:
Map<String, Object> attributes = new HashMap<String, Object>();
Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
for(Map.Entry<String,JsonElement> entry : entrySet){
attributes.put(entry.getKey(), jsonObject.get(entry.getKey()).getAsString());
}
Note there are many other methods you can call on a JsonElement to produce other types.
I am not quite sure why you want to do manual manipulation in the first place. GSON decode will simply leave those absent key/value pairs as default value (zero,null). And then you can process as you want.
I have a JSONObject with some attributes that I want to convert into a Map<String, Object>
Is there something that I can use from the json.org or ObjectMapper?
You can use Gson() (com.google.gson) library if you find any difficulty using Jackson.
//changed yourJsonObject.toString() to yourJsonObject as suggested by Martin Meeser
HashMap<String, Object> yourHashMap = new Gson().fromJson(yourJsonObject, HashMap.class);
use Jackson (https://github.com/FasterXML/jackson) from http://json.org/
HashMap<String,Object> result =
new ObjectMapper().readValue(<JSON_OBJECT>, HashMap.class);
This is what worked for me:
public static Map<String, Object> toMap(JSONObject jsonobj) throws JSONException {
Map<String, Object> map = new HashMap<String, Object>();
Iterator<String> keys = jsonobj.keys();
while(keys.hasNext()) {
String key = keys.next();
Object value = jsonobj.get(key);
if (value instanceof JSONArray) {
value = toList((JSONArray) value);
} else if (value instanceof JSONObject) {
value = toMap((JSONObject) value);
}
map.put(key, value);
} return map;
}
public static List<Object> toList(JSONArray array) throws JSONException {
List<Object> list = new ArrayList<Object>();
for(int i = 0; i < array.length(); i++) {
Object value = array.get(i);
if (value instanceof JSONArray) {
value = toList((JSONArray) value);
}
else if (value instanceof JSONObject) {
value = toMap((JSONObject) value);
}
list.add(value);
} return list;
}
Most of this is from this question: How to convert JSONObject to new Map for all its keys using iterator java
The best way to convert it to HashMap<String, Object> is this:
HashMap<String, Object> result = new ObjectMapper().readValue(jsonString, new TypeReference<Map<String, Object>>(){}));
Note to the above solution (from A Paul):
The solution doesn't work, cause it doesn't reconstructs back a HashMap< String, Object > - instead it creates a HashMap< String, LinkedHashMap >.
Reason why is because during demarshalling, each Object (JSON marshalled as a LinkedHashMap) is used as-is, it takes 1-on-1 the LinkedHashMap (instead of converting the LinkedHashMap back to its proper Object).
If you had a HashMap< String, MyOwnObject > then proper demarshalling was possible - see following example:
ObjectMapper mapper = new ObjectMapper();
TypeFactory typeFactory = mapper.getTypeFactory();
MapType mapType = typeFactory.constructMapType(HashMap.class, String.class, MyOwnObject.class);
HashMap<String, MyOwnObject> map = mapper.readValue(new StringReader(hashTable.toString()), mapType);
The JSONObject has a method toMap which returns Map<String,Object>.
The Maven dependency used in pom.xml:
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>current-version</version>
</dependency>
You can find the current-version here.
Found out these problems can be addressed by using
ObjectMapper#convertValue(Object fromValue, Class<T> toValueType)
As a result, the origal quuestion can be solved in a 2-step converison:
Demarshall the JSON back to an object - in which the Map<String, Object> is demarshalled as a HashMap<String, LinkedHashMap>, by using bjectMapper#readValue().
Convert inner LinkedHashMaps back to proper objects
ObjectMapper mapper = new ObjectMapper();
Class clazz = (Class) Class.forName(classType);
MyOwnObject value = mapper.convertValue(value, clazz);
To prevent the 'classType' has to be known in advance, I enforced during marshalling an extra Map was added, containing <key, classNameString> pairs. So at unmarshalling time, the classType can be extracted dynamically.
This is how I did it in Kotlin:
mutableMapOf<String, Any>().apply {
jsonObj.keys().forEach { put(it, jsonObj[it]) }
}
import com.alibaba.fastjson.JSONObject;
Map<String, Object> map = new HashMap<String, Object>();
JSONObject rec = JSONObject.parseObject(<JSONString>);
map.put(rec.get("code").toString(), rec.get("value").toString());
I am writing a java code to insert form values into mongoDB using java code. I am using map to retrieve all the values from the map and inserting it into mongoDB. However, if an attribute is having multiple values, it is only inserting only one value. My code is:
Map<String, String[]> articleData = request.getParameterMap();
for(String key : articleData.keySet())
{
for(int i=0; i<articleData.get(key).length;i++)
{
document.put(key,articleData.get(key)[i]);
}
}
table.insert(document);
However, right now, it is overriding the values of the attribute having multiple values.
How can I resolve it?
Try this, It will give you a basic idea. Adjust code according to your program:
Map<String, String[]> articleData = request.getParameterMap();
for(String key : articleData.keySet())
{
BasicDBObject data =new BasicDBObject();
for(int i=0; i<articleData.get(key).length;i++)
{
data.put("",articleData.get(key)[i]);
}
document.put(key,data);
}
table.insert(document);
Encode a JSON object .
Try this out.
Map<String, String[]> articleData = request.getParameterMap();
for(String key : articleData.keySet())
{
JSONObject out = new JSONObject();
out.put("key", key);
out.put("value", articleData.get(key));
System.out.println(out);
}
dbobj.put("multiple",out);
collection.insert(dbobj);