Java Android Array Key value - java

There is any data structure in java that i can work like a key value array from php or javascript?
$objectKeyTarget = "key2";
$array = array(
"key1": {
"id": 1,
"name" "exemple 1"
},
"key2": {
"id": 2,
"name" "exemple 2"
}
);
$dynamicObject = $array[$objectKeyTarget];

Well you could simply use a Map and a List for that. I'd suggest something like this:
public class Entry {
private int id;
private String name;
...
}
Map<String, List<Entry>> entriesByKey = new HashMap<>;
entriesByKey.put("key1", new Entry(1,"exemple 1"));
entriesByKey.put("key2", new Entry(2,"exemple 2"))
Log.d(..., entriesByKey.get("key2"));
If you are trying to store a JSON-Respone: There is in-built JSONObject in Android, so use that one instead.

The simple way
not_array = {
'Y':'YES',
'N':'NO',
'M': {'MY':'MAYBE YES','MN':'MAYBE NO'}
}
value = 'Y';
result = not_array[value];
console.log(result);
value1 = 'M';
value2 = 'MN';
result1 = not_array[value1][value2];
console.log(result1);

Related

Generate a String from all values of a specific key from List<Map> in Java?

Suppose I have a list of Map such as:
(Using json format just for demonstration)
List<Map> myList = [
{
"id": 12,
"name": "Harie"
},
{
"id": "Forty",
"location": "Earth"
},
{
"name": "Potah"
},
{
"id": "0"
}
]
Now I want all the "id" values in a single String object, separated by a separator.
For example, the above map should give me:
"12#Forty#0"
Note:
The order in which they are indexed in the list has to be maintained.
I know I can do it like this:
StringBuilder result = new StringBuilder();
for (Map map : myList) {
if (map.get("id") instanceof String) {
if(result.length()>0){
result.append('#');
}
result.append(map.get("id"));
}
}
//Use result.toString() for output
But I want a more readable and simplified code, preferably using Java stream api.
You can use stream and join all the key id values which are not null
String keyString = myList.stream()
.map(map->map.get("id"))
.filter(Objects::nonNull)
.map(Object::toString)
.collect(Collectors.joining("#"));
In case if you want to check if the value is String instance you can filter
filter(val-> val!=null && val instance String)
StringBuilder sb = new StringBuilder();
myList.stream().map((mapping) => {
sb.append(mapping.get(id))
sb.append("#")
}
You can add extra logic within the lambda function!

how to access array list and validate the value with AND conditions

I got the response as follow:
{
"cartId": "default",
"cartLines": [
{
"testid": "123",
"isDeleted": false,
"name": "peter",
},
{
"testid": "123",
"isDeleted": true,
"name": "mary",
}
],
"type": "test"
}
I would like to make sure the value of "name": "peter"
when query condition is "testid": "123" AND "isDeleted": false
what class can i use? Either java or groovy scripting language is good.
this is the usual way i did assertion, straightforward. the println(test_info) returned response i gave at above.
now i wanted to use for more conditions.
//SQL statement
String dbQuery2 = /SELECT * FROM public.tests where test_id = 'default'/
//Connect to PostgresSQL, global variable is stored at profile
List results = CustomKeywords.'test.database.getPostgresSQLResults'(GlobalVariable.dbConnString2 , GlobalVariable.dbUsername2 , GlobalVariable.dbPassword2 ,GlobalVariable.dbDriver2 ,dbQuery2 )
println(results)
//print the "test_info" column
String test_info = results.get(0).get('test_info')
println(test_info)
//convert to json format and verify result
def test_infojson = new JsonSlurper().parseText(new String(test_info))
println('Database test_info response text: \n' + JsonOutput.prettyPrint(JsonOutput.toJson(test_infojson)))
assert test_info.contains("peter")
The below solution is in java:
You need have a class to represent your JSON structure.
class Response {
String cardId;
String type;
List<Cartline> cartlines;
//Constructor
//Getters and Setters
}
class Cartline {
String name;
String testid;
boolean isDeleted;
//Constructor
//Getters and Setters
}
Then in your main code, you can do as shown below:
import org.json.*;
String jsonString = ... ; //assign your JSON String here
JSONObject obj = new JSONObject(jsonString);
JSONArray arr = obj.getJSONArray("cartLines");
for (int i = 0; i < arr.length(); i++)
{
String name = arr.getJSONObject(i).getString("name");
String testId = arr.getJSONObject(i).getString("testId");
Boolean isDeleted = arr.getJSONObject(i).getBoolean("isDeleted");
if (name.equals("peter") && testId. equals("123") && isDeleted == false) {
// do your stuff
}
}
You can access the jar file here : http://mvnrepository.com/artifact/org.json/json

Dynamic way to access JSON nested values in Java

I have this JSON object:
{
"maindrawer":
{
"enabled": true,
"actions":
[
{
"type": "Section",
"title": "Section 1"
},
{
"id": 1,
"type": "Primary",
"title": "Title 1",
"badge":
{
"enabled": false,
"value": 0,
"textColor": "#000000",
"badgeColor": "#ff0990"
},
"subActions":
[
{
"id": 1,
"type": "Primary",
"title": "Sub Title 1"
}
]
}
]
}
}
This is the code I'm using to access the badge -> textColor value:
public void loadJSONFromRaw(Context context, int id)
{
json = null;
try
{
//read and return json sting
InputStream is = context.getResources().openRawResource(id);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
//convert json to object
Type type = new TypeToken<Map<String, Object>>() {}.getType();
Map<String, Object> data = new Gson().fromJson(json, type);
//access maindrawer property
Map<String, Object> maindrawer = (Map<String, Object>)data.get("maindrawer");
//access actions list
List<Object> actions = (List<Object>)maindrawer.get("actions");
//return first item in the list
Map<String, Object> action = (Map<String, Object>) actions.get(1);
//return badge object
Map<String, String> badge = (Map<String, String>) action.get("badge");
//access badge -> textColor value
String textColor = badge.get("textColor");
}
catch (IOException e)
{
e.printStackTrace();
}
}
Is there a better/faster or more dynamic way to access JSON nested properties using java/android? I'm using Gson library for this task and don't mind to switch to any other solution to make it easier as this is too much of code to write just to access a single variable.
Ideally, I'm looking for something like:
String textColor = data.get("maindrawer").get("actions").get(1).get("badge").get("textColor");
Also I'm not very interested in using POJO for now.
Lastly, I'm still new to Java so I'm probably missing something here or maybe there are some limitations? anyways thanks for you help!!
Found what I need using JsonPath library. It looks like it does similar to what I need. Here's a sample code I found:
String textColor = JsonPath.parse(json).read("$.maindrawer.actions[1].badge.textColor");
Very clean and straightforward. Hopes this will save someone else's time as well.
Since you are accessing json file locally, it means you know its structure.
So instead of using -
Map<String, Object> data = new Gson().fromJson(json, type);
You can use something like this-
Map<String, MainDrawer> data = new Gson().fromJson(json, type);
where MainDrawer is a class with member variables - enabled, actions and array of another type.
That would make easier to fetch your values like using -
mainDrawer.isEnabled()
Here are two solutions without importing a new library.
Write a simple path parser:
String textColor = (String)parse(data, "maindrawer", "actions", 1, "badge", "textColor");
//...
static Object parse(Object root, Object... params) {
Object current = root;
for (Object p : params) {
if (p instanceof Number) {
current = ((List<?>)current).get(((Number)p).intValue());
} else {
current = ((Map<?,?>)current).get(p.toString());
}
}
return current;
}
Or parse and walk through Gson's JsonElement:
JsonElement root = new Gson().fromJson(json, JsonElement.class);
String textColor = root
.getAsJsonObject().get("maindrawer")
.getAsJsonObject().get("actions")
.getAsJsonArray().get(1)
.getAsJsonObject().get("badge")
.getAsJsonObject().get("textColor")
.getAsString();
You can also do this with BSON using a single line query. You have to cast the object to the type as you go down into Nested JSON objects.
//import java.util.ArrayList;
//import org.bson.Document;
Document root = Document.parse("{ \"maindrawer\" : { \"enabled\" : true, \"actions\" : [{ \"type\" : \"Section\", \"title\" : \"Section 1\" }, { \"id\" : 1, \"type\" : \"Primary\", \"title\" : \"Title 1\", \"badge\" : { \"enabled\" : false, \"value\" : 0, \"textColor\" : \"#000000\", \"badgeColor\" : \"#ff0990\" }, \"subActions\" : [{ \"id\" : 1, \"type\" : \"Primary\", \"title\" : \"Sub Title 1\" }] }] } }");
System.out.println(((String)((Document)((Document)((ArrayList)((Document)root.get("maindrawer")).get("actions")).get(1)).get("badge")).get("textColor")));

Parse JSON with dynamic key object inside dynamic key object with Gson

I am a newbie to android and I have a JSON file with dynamic key like this:
{
"x": {
"a": {
"1": [1,2,3,4],
"2": [1,2,3,4]
},
"b": {
"1": [1,2,3,4],
"2": [1,2,3,4]
}
},
"y": {
"a": {
"1": [1,2,3,4],
"2": [1,2,3,4]
},
"b": {
"1": [1,2,3,4],
"2": [1,2,3,4]
}
},
"z": {
"a": {
"1": [1,2,3,4],
"2": [1,2,3,4]
},
"b": {
"1": [1,2,3,4],
"2": [1,2,3,4]
}
}
}
I parsed it successfully by JSONObject but I have to loop by keys Iterator on x, y, z. For each time, I have to loop on a, b and the same for "1" and "2". I think it's not a good solution. I created models for them like this:
Class XYZ {
private String name; // "x", "y", "z" value
private ArrayList<ABC> abcList;
}
Class ABC {
private String name; // "a", "b", "c"
private ArrayList<Item> itemList;
}
Class Item{
private String ID; // "1", "2"
private int[] valueArray;
}
Can anyone help me to parse this json by Gson, I think it looks more professional :D. Thank you so much
Your models cannot map your JSON just because Gson default configuration clearly gets them unmatched.
You can have two "default" ways:
static
... since you didn't really mention why your JSON is considered dynamic:
final class XYZ {
final ABC x = null;
final ABC y = null;
final ABC z = null;
}
final class ABC {
final OneTwo a = null;
final OneTwo b = null;
}
final class OneTwo {
#SerializedName("1")
final List<Integer> one = null;
#SerializedName("2")
final List<Integer> two = null;
}
Example:
try ( final Reader reader = getPackageResourceReader(Q43695739.class, "dynamic.json") ) {
final XYZ xyz = gson.fromJson(reader, XYZ.class);
System.out.println(xyz.x.b.two);
}
dynamic (by deserialization)
... assuming your keys are dynamic, but the structure remains the same:
private static final Type stringToStringToStringToIntegerListType = new TypeToken<Map<String, Map<String, Map<String, List<Integer>>>>>() {
}.getType();
try ( final Reader reader = getPackageResourceReader(Q43695739.class, "dynamic.json") ) {
final Map<String, Map<String, Map<String, List<Integer>>>> m = gson.fromJson(reader, stringToStringToStringToIntegerListType);
System.out.println(m.get("x").get("b").get("2"));
}
dynamic (by JSON trees)
Another true dynamic approach that may be helpful for some scenarios. Also note that JSONObject is not in the Gson realm: you probably might have imported this one from the org.json package. Gson uses camel-cased names like JsonElement, JsonObject, etc.
try ( final Reader reader = getPackageResourceReader(Q43695739.class, "dynamic.json") ) {
final JsonElement jsonElement = gson.fromJson(reader, JsonElement.class)
.getAsJsonObject()
.getAsJsonObject("x")
.getAsJsonObject("b")
.getAsJsonArray("2");
System.out.println(jsonElement);
}
The first and the second examples produce java.util.List instances
[1, 2, 3, 4]
The third example returns a JsonArray instance with a slightly different toString implementation:
[1,2,3,4]

Parsing nested JSON

I have the following JSON:
{
"registration": {
"name": "Vik Kumar",
"first_name": "Vik",
"last_name": "Kumar",
"bloodGroup": "B-",
"gender": "male",
"birthday": "10\/31\/1983",
"email": "vik.ceo\u0040gmail.com",
"cellPhone": "1234123456",
"homePhone": "1234123457",
"officePhone": "1234123458",
"primaryAddress": "jdfjfgj",
"area": "jfdjdfj",
"location": {
"name": "Redwood Shores, California",
"id": 103107903062719
},
"subscribe": true,
"eyePledge": false,
"reference": "fgfgfgfg"
}
}
I am using the following code to parse it:
JsonNode json = new ObjectMapper().readTree(jsonString);
JsonNode registration_fields = json.get("registration");
Iterator<String> fieldNames = registration_fields.getFieldNames();
while(fieldNames.hasNext()){
String fieldName = fieldNames.next();
String fieldValue = registration_fields.get(fieldName).asText();
System.out.println(fieldName+" : "+fieldValue);
}
This works fine and it print all the values except for location which is kind of another level of nesting. I tried the same trick as above code to pass json.get("location") but that does not work. Please suggest how to make it work for location.
You need to detect when you are dealing with a (nested) Object using JsonNode#isObject:
public static void printAll(JsonNode node) {
Iterator<String> fieldNames = node.getFieldNames();
while(fieldNames.hasNext()){
String fieldName = fieldNames.next();
JsonNode fieldValue = node.get(fieldName);
if (fieldValue.isObject()) {
System.out.println(fieldName + " :");
printAll(fieldValue);
} else {
String value = fieldValue.asText();
System.out.println(fieldName + " : " + value);
}
}
}
Thus, when you reach an object, such as location, you'll call the printAll recursively to print all its inner values.
org.codehaus.jackson.JsonNode json = new ObjectMapper().readTree(jsonString);
org.codehaus.jackson.JsonNode registration_fields = json.get("registration");
printAll(registration_fields);
Since location is nested within registration, you need to use:
registration_fields.get("location");
to get it. But isn't it already processed by the while-loop, why do you need to get it separately?

Categories