I am quite new to java and android so please keep that in mind.
I have an Arraylist of an Arraylist of integers. These integers are data from the GPS like Latitude, longtitude, speed at that moment and distance, added to an arraylist in OnLocationChanged and all these arraylists are then added to another arraylist.(sort of like a matrix or table)
example: [[timestamp,lat,long,distance_from_start,speed],[...],...] (all are integers)
I want to convert this Arraylist of arraylists so i can save it on the internal storage of my app for use in other activities ( like statistics of this data) and to upload it to a server. I have searched around quite a bit and found that converting an arraylist to json allows this and also makes it easier to create an SQL file of this data. The conversion of the arraylist to json seems easy enough but i can't find any examples of converting an arraylist of arraylists to json. So i dont know if the arraylists in the arraylist are converted to jsonarrays or whatever or if they will be usable and readable from the json file at all. If this is not possible, are there any other alternative ways of doing this?
Thanks a lot!
Use org.json.JsonArray library.
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
public class Test {
public static void main(String[] args) {
List<List<Integer >> list= new ArrayList<List<Integer>>();
List<Integer> list1=new ArrayList();
list1.add(10);
list1.add(20);
list.add(list1);
List<Integer> list2=new ArrayList();
list2.add(60);
list2.add(70);
list.add(list2);
JSONArray jsonArray= new JSONArray(list);
System.out.println(jsonArray);
}
}
output:
[[10,20],[60,70]]
You can use Gson from Google.
Your main functions are: toJson and fromJson.
From the javadoc:
toJson(Object src)
This method serializes the specified object into its equivalent Json representation.
fromJson(String json, Type typeOfT)
This method deserializes the specified Json into an object of the specified type.
For example:
(Serialization)
Gson gson = new Gson();
gson.toJson(1); ==> prints 1
gson.toJson("abcd"); ==> prints "abcd"
gson.toJson(new Long(10)); ==> prints 10
int[] values = { 1 };
gson.toJson(values); ==> prints [1]
(Deserialization)
int one = gson.fromJson("1", int.class);
Integer one = gson.fromJson("1", Integer.class);
Long one = gson.fromJson("1", Long.class);
Boolean false = gson.fromJson("false", Boolean.class);
String str = gson.fromJson("\"abc\"", String.class);
String anotherStr = gson.fromJson("[\"abc\"]", String.class);
Object Examples
class BagOfPrimitives {
private int value1 = 1;
private String value2 = "abc";
private transient int value3 = 3;
BagOfPrimitives() {
// no-args constructor
}
}
(Serialization)
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);
==> json is {"value1":1,"value2":"abc"}
Note that you can not serialize objects with circular references since that will result in infinite recursion.
(Deserialization)
BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);
==> obj2 is just like obj
List of Lists of Integers
List<List<Integer >> list = new ArrayList<List<Integer>>();
List<Integer> list1=new ArrayList();
list1.add(100);
list1.add(200);
list.add(list1);
List<Integer> list2=new ArrayList();
list2.add(700);
list2.add(800);
list.add(list2);
Gson gson = new Gson()
String json = gson.toJson(list);
System.out.println(json);
Related
I have a following JSON:
{"data":["str1", "str2", "str3"]}
I want to get a List, i.e. ["str1", "str2", "str3"]
My code is:
JSONObject json = new JSONObject();
List list = new ArrayList();
...
// adding data in json
...
list = (List) json.get("data");
This is not working.
you can get this data as a JsonArray
You can customize a little bit of code like it
public static void main(String[] args) throws ParseException {
String data = "{\"data\":[\"str1\", \"str2\", \"str3\"]}";
JSONObject json = new JSONObject(
data);
JSONArray jasonArray = json.getJSONArray("data");
List list = new ArrayList();
int size = jasonArray.length();
int i = 0;
while (i < size) {
list.add(jasonArray.get(i));
i++;
}
System.out.println(list);
}
You wish to parse a JSON string using Java code. It is recommended to use a JSON library for Java. There are several. The below code uses Gson. There are many online examples such as Convert String to JsonObject with Gson. You should also familiarize yourself with the Gson API.
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.ArrayList;
import java.util.List;
public class JsonList {
public static void main(String[] args) {
String json = "{\"data\":[\"str1\", \"str2\", \"str3\"]}";
JsonElement elem = JsonParser.parseString(json);
if (elem.isJsonObject()) {
JsonObject obj = elem.getAsJsonObject();
elem = obj.get("data");
if (elem.isJsonArray()) {
JsonArray arr = elem.getAsJsonArray();
List<String> list = new ArrayList<>();
int count = arr.size();
for (int i = 0; i < count; i++) {
elem = arr.get(i);
if (elem.isJsonPrimitive()) {
String str = elem.getAsString();
list.add(str);
}
}
System.out.println(list);
}
}
}
}
Running the above code gives the following output:
[str1, str2, str3]
There are other ways to convert the JsonArray to a List. The above is not the only way. As I wrote earlier, peruse the API documentation and search the Internet.
Behind the scenes, the JSONArray object stores the json data in an ArrayList<Object>, and it has a method called toList(). There's absolutely no need to loop through the JSONArray in order to set values in the array. The simpler code would look something like this
String data = "{\"data\":[\"str1\", \"str2\", \"str3\"]}";
JSONObject json = new JSONObject(data);
List<Object> list = json.getJSONArray("data").toList();
System.out.println(myList);
Note: This will create a list of generic Objects. The currently accepted answer doesn't define a type for the List, which is unsafe. It doesn't enforce type safety, and errors will occur at runtime instead of at compile time.
If you want to convert all of the inner objects to a String, you can do this by upcasting the List to an Object, and then casting it to a List<String>. I don't particularly recommend it, but it can be done like this. List<String> list = (List<String>) (Object) json.getJSONArray("data").toList();.
A better way of casting the value to a specific type would be via a stream to call the Object.toString() method.
List<String> list = json.getJSONArray("data").toList().stream().map(Object::toString).collect(Collectors.toList());
or, if you have a specific type you want to cast it to, you can use
List<MyObject> list = json.getJSONArray("data").toList().stream().map(jsonObject -> (MyObject) jsonObject).collect(Collectors.toList());
Finally, as others have pointed out, there are better libraries for dealing with json. Gson is a great library, however I personally prefer Jackson. They both offer similar resources, but I've found that Jackson's ObjectMapper is more customizable and more widely used.
This question already has answers here:
Testing two JSON objects for equality ignoring child order in Java [closed]
(28 answers)
Closed 7 years ago.
I have a string like - {"state":1,"cmd":1} , I need to compare this with generated output but in the generated output the order keeps changing i.e. sometimes its {"state":1,"cmd":1} other times its {"cmd":1,"state":1}.
Currently I was using equals() method to compare, What can be better way in this scenario to validate the two strings. My concern is just that both entries are present in string, order is not imp.
Jackson Json parser has a nice feature that it can parse a Json String into a Map. You can then query the entries or simply ask on equality:
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.*;
public class Test
{
public static void main(String... args)
{
String input1 = "{\"state\":1,\"cmd\":1}";
String input2 = "{\"cmd\":1,\"state\":1}";
ObjectMapper om = new ObjectMapper();
try {
Map<String, Object> m1 = (Map<String, Object>)(om.readValue(input1, Map.class));
Map<String, Object> m2 = (Map<String, Object>)(om.readValue(input2, Map.class));
System.out.println(m1);
System.out.println(m2);
System.out.println(m1.equals(m2));
} catch (Exception e) {
e.printStackTrace();
}
}
}
The output is
{state=1, cmd=1}
{cmd=1, state=1}
true
You can also use Gson API
JsonParser parser = new JsonParser();
JsonElement o1 = parser.parse("{\"state\":1,\"cmd\":1}");
JsonElement o2 = parser.parse("{\"cmd\":1,\"state\":1}");
System.out.println(o1.equals(o2));
Try this
import java.util.*;
import com.google.gson.*;
public class CompareArray {
static Set<JsonElement> setOfElements(JsonArray arr) {
Set<JsonElement> set = new HashSet<JsonElement>();
for (JsonElement j: arr) {
set.add(j);
}
return set;
}
public static void main(String[] args) {
JsonParser parser = new JsonParser();
Set<JsonElement> arr1elems =
setOfElements(parser.parse(args[0]).getAsJsonArray());
Set<JsonElement> arr2elems =
setOfElements(parser.parse(args[1]).getAsJsonArray());
System.out.println("Arrays match? " + arr1elems.equals(arr2elems));
}
}
$ java -cp .:gson-2.2.2.jar CompareArray '[{"key1":"value1"},
{"key2":"value2"}, {"key3":"value3"}]' '[{"key3":"value3"},
{"key1":"value1"}, {"key2":"value2"}]'
Arrays match? true
I trust this is helpful to you.
You can simply use a class to define your object and JSONObject to parse your JSON object and get its properties:
Java Class:
public class MyObject{
private String state; //either int or String
private String cmd;
//getters and setters
}
Your parsing should be like this:
MyObject obj = new MyObject();
JSONParser jsonParser = new JSONParser();
// input is your string here
JSONObject jsonObject = (JSONObject) jsonParser.parse(input);
//get properties here and set them in your object
obj.setState(jsonObject.get("state"));
obj.setCmd(jsonObject.get("cmd"));
And then when you have the two objects you can easily compare their properties.
I am trying to insert data into multiple JSON objects but I don't know how to create them dynamically in android.
In the hard coded way it is something like:-
JSONArray pdoInformation = new JSONArray();
JSONObject pDetail1 = new JSONObject();
JSONObject pDetail2 = new JSONObject();
JSONObject pDetail3 = new JSONObject();
pDetail1.put("productid", 1);
pDetail1.put("qty", 3);
pDetail1.put("listprice", 9500);
pDetail2.put("productid", 2);
pDetail2.put("qty", 4);
pDetail2.put("listprice", 8500);
pDetail3.put("productid", 3);
pDetail3.put("qty", 2);
pDetail3.put("listprice", 1500);
pdoInformation.put(pDetail1);
pdoInformation.put(pDetail2);
pdoInformation.put(pDetail3);
But I want to create these JSONObject dynamically as I don't know how many of them are going to be needed while coding and in those dynamically created JSONObject the data will be filled from three ArrayList of productid, qty and listprice.
So its obvious that the number of those dynamically created JSONObject will depend on the size of any one ArrayList.
ArrayList :-
ArrayList<String> productid = new ArrayList<String>();
ArrayList<String> qty = new ArrayList<String>();
ArrayList<String> listprice= new ArrayList<String>();
List<JSONObject> myJSONObjects = new ArrayList<JSONObject> (productid.size());
for(int i=0; i<productid.size(); i++) {
JSONObject obj = new JSONObject();
obj.put("productid", productid.get(i) );
obj.put("qty", qty.get(i));
obj.put("listprice", listprice.get(i));
myJSONObjects.add(obj);
}
at the end all JSONObjects are in myJSONObjects.
I want to create these JSONObject dynamically as I don't know how many
of them are going to be needed while coding.
As you are already having ArrayList, iterate through it and create a new JSONObject in each iteration and put it inside ArrayList<JSONObject>.
For example:
JSONObject objJSON;
for(int i=0; i<numberOfItems; i++) {
objJSON = new JSONObject();
objJSON.put("productid", 1);
objJSON.put("qty", 3);
objJSON.put("listprice", 9500);
pdoInformation.put(objJSON);
}
The data will be filled from three ArrayList of productid, qty and
listprice
You shouldn't take different ArrayLists because you have to manage each lists as many as you have, instead of that create a single ArrayList of type user defined class. For example, ArrayList<Product> where Product type would contain setter/getter methods.
In this design, how will you relate data with each other if it is divided in multiple Arraylists.
It seems you need to redesign your data structure a bit.
Instead of using three ArrayLists you should keep one Arraylist.
That Arraylist will hold object of beans.
For ex.
class product{
private double productid;
private double listprice;
private long qty;
// getters and setters
}
and keep all objects in one Arraylist and then by looping through it you get all three values together while creating JSON.
JSON is just a text String. You could simply write something like:
String jsonString = "[";
jsonString = jsonString + "{\""productid\":1",\"qty\":3,\"listprice\":9500}";
jsonString = jsonString + "{\""productid\":2",\"qty\":4,\"listprice\":8500}";
jsonString = jsonString + "{\""productid\":3",\"qty\":2,\"listprice\":1500}";
...
jsonString = jsonString + "]";
This could be the raw way of doing it.
I am using (not in android but in jsp, so could not be posible) gson and it also works with arraylist object, so you can create the array of objects and after that just ask him to generate the json text.
I'm trying to decode a simple two dimensional array of ints I'm getting from javascript, but can't figure it out.
I've tried to use Gson, but couldn't figure out what is the class of the array:
int[][] newMap;
Gson gson = new Gson();
newMap = gson.fromJson (req.getParameter("map"), ?????);
Update: more info
I'm sending a simple 2D array from javascript. that's pretty much the relevant code:
var mapData = new Array(30);
for ( var i = 0; i < mapData.length; i++ ){
mapData[i] = new Array(30);
}
......
$.post('/create_map', { map : JSON.stringify(mapData) } )
in between i'm populating with integers. i just want to send to a servlet and have a 2D array in java
You can try something like this if you want:-
int[][] dummy = new int[0][0]; // The same type as your "newMap"
int[][] newMap;
Gson gson = new Gson();
newMap = gson.fromJson(req.getParameter("map"), dummy.getClass());
I wish to use GSON to parse the following json:
[
[
"hello",
1,
[2]
],
[
"world",
3,
[2]
]
]
So, that's 1 array, containing 2 arrays. The 2 inner arrays are themselves arrays, comprised of String, int, array types.
I'm unsure how I can using Java classes to model the array which has 3 different types (String, int, array). I start with:
// String json just contains the aforementioned json string.
ArrayList<ArrayList<XXX>> data = new ArrayList<ArrayList<XXX>>();
Type arrayListType = new TypeToken<ArrayList<ArrayList<XXX>>>(){}.getType();
data = gson.fromJson(json, arrayListType);
But what should be where the 'XXX' are? I think it should be an array, but it should be an array with 3 different data types. So how can I use Java to model this?
Can any help?
Thank you.
Gson has special handling for deserializing some single-component arrays into a non-array type. For example, int data = gson.fromJson("[3]", int.class); would assign the int value 3 to data.
Of course, deserializing a single-component array into a non-array type is not required. For example, the previous example could be deserialized as int[] data = gson.fromJson("[3]", int[].class);.
Gson will also often deserialize a non-String value into a String, when asked. Applying this to the first example, String data = gson.fromJson("[3]", String.class); works just as well.
Note that it does not work to tell Gson to deserialize the first example as type Object. Object data = gson.fromJson("[3]", Object.class); results in a parse exception complaining that [3] is not a primitive.
Applied to the example in the original question above, if it's acceptable to treat all of the values as Strings, then deserialization becomes simple.
// output:
// hello 1 2
// world 3 2
public class Foo
{
static String jsonInput =
"[" +
"[\"hello\",1,[2]]," +
"[\"world\",3,[2]]" +
"]";
public static void main(String[] args)
{
Gson gson = new Gson();
String[][] data = gson.fromJson(jsonInput, String[][].class);
for (String[] data2 : data)
{
for (String data3 : data2)
{
System.out.print(data3);
System.out.print(" ");
}
System.out.println();
}
}
}
Unfortunately, with Gson I've not been able to figure out a simple deserialization approach that would allow for "better" binding to more specific and mixed types in an array, since Java doesn't provide a syntax for defining a mixed type array. For example, the preferred type of the collection in the original question might be List<List<String, int, List<int>>>, but that's not possible to define in Java. So, you gotta be content with List<List<String>> (or String[][]), or turn to an approach with more "manual" parsing.
(Yes, Java allows a type declaration of List<List<Object>>, but Object is not a specific enough type to meaningfully deserialize to. Also, as discussed, attempting to deserialize [3] to Object results in a parse exception.)
Small Update: I recently had to deserialize some sloppy JSON that included a structure not too dissimilar from that in the original question. I ended up just using a custom deserializer to create a object from the messy JSON array. Similar to the following example.
// output:
// [{MyThreeThings: first=hello, second=1, third=[2]},
// {MyThreeThings: first=world, second=3, third=[4, 5]}]
import java.lang.reflect.Type;
import java.util.Arrays;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
public class FooToo
{
static String jsonInput =
"[" +
"[\"hello\",1,[2]]," +
"[\"world\",3,[4,5]]" +
"]";
public static void main(String[] args)
{
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(MyThreeThings.class, new MyThreeThingsDeserializer());
Gson gson = gsonBuilder.create();
MyThreeThings[] things = gson.fromJson(jsonInput, MyThreeThings[].class);
System.out.println(Arrays.toString(things));
}
}
class MyThreeThings
{
String first;
int second;
int[] third;
MyThreeThings(String first, int second, int[] third)
{
this.first = first;
this.second = second;
this.third = third;
}
#Override
public String toString()
{
return String.format(
"{MyThreeThings: first=%s, second=%d, third=%s}",
first, second, Arrays.toString(third));
}
}
class MyThreeThingsDeserializer implements JsonDeserializer<MyThreeThings>
{
#Override
public MyThreeThings deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException
{
JsonArray jsonArray = json.getAsJsonArray();
String first = jsonArray.get(0).getAsString();
int second = jsonArray.get(1).getAsInt();
JsonArray jsonArray2 = jsonArray.get(2).getAsJsonArray();
int length = jsonArray2.size();
int[] third = new int[length];
for (int i = 0; i < length; i++)
{
int n = jsonArray2.get(i).getAsInt();
third[i] = n;
}
return new MyThreeThings(first, second, third);
}
}
The Gson user guide does cover handling deserialization of collections of mixed types with a similar example as this in the "Serializing and Deserializing Collection with Objects of Arbitrary Types" section.
First, I think you may be mistaken in your example above. An Array consisting of three different is a very unusual approach, to say the least. Probably your json structure is an array, containing tuples. These tuples then include an array.
Like:
[
{
"hello",
1,
[2]
},
{
"world",
3,
[2]
}
]
XXX should be an object containing:
A String
An int (or Integer)
An Array of (I guess) ints.
Then you make an array of these objects and parse the json into it.
However, your json seems really badly formed, since all members should be named, like
[
{
"str":"hello",
"intVal":1,
"intArr":[2]
},
{
"str":"world",
"intVal":3,
"intArr":[2]
}
]
If, on the other hand, the JSON really looks the way you describe it, you would have to make arrays of Object, plain and simple, and then cast them when you read them from your data structure.