How to iterate through a Map inside another Map Java - java

I have a map that contains data below, and I want to process the data inside the key bookAttr
{
"form46": {
"bookId": 46,
"bookAttr": {
"title": "To Kill a Mockingbird",
"author": "Harper Lee"
}
},
"form47": {
"bookId": 66,
"bookAttr": {
"title": "1984",
"author": "George Orwell"
}
}
}
I tried to iterate on the initial map, however I am getting an error when trying to process the values that I have since Java is complaining that Object cannot be converted to HashMap
HashMap<String, Object> bookForm; // contains bookFormData
for (Object value : bookForm.values()) {
HashMap<String,Object> bookAttributes = value.get("bookAttr");
System.out.println(bookAttributes);
//iterate over bookAttributes and do something else
}
How can iterate over bookAttr to be able to process its contents?
Contents of bookForm:
bookForm.entrySet().stream().forEach(e
-> System.out.println(e.getKey() + "=" + e.getValue())
);
Output:
form46={bookAttr={title=To Kill a Mockingbird, author=Harper Lee}, bookId=46}
form47={bookId=66, bookAttr={title=1984, author=George Orwell}}

Seems like the problem is that you are trying to set the Object value to variable of HashMap type. And, also try using Map instead of HashMap.
Try to replace
HashMap<String,Object> bookAttributes = value.get("bookAttr");
with
Map<String,Object> bookAttributes = (Map<String, Object>)value.get("bookAttr");

Related

How to add JSON values to an ArrayList in Java

I have the following JSON file:
{
"meta" : {
"stock" : "AWS",
"date modified" : 90
},
"roles" : [ "Member", "Admin" ],
"name" : "John Doe",
"admin" : true,
"email" : "john.doe#example.com"
}
I wanted to both read the values of the keys and add them to an Array List.
try {
// create object mapper instance
ObjectMapper mapper = new ObjectMapper();
// convert JSON file to map
Map<?, ?> map = mapper.readValue(Paths.get("user.json").toFile(), Map.class);
ArrayList<String> data = new ArrayList<String>();
// print map entries
for (Map.Entry<?, ?> entry : map.entrySet()) {
System.out.println((entry.getClass()) + " " + entry.getValue());
data.add((String)entry.getValue()); // trying to add entry values to arraylist
}
} catch (Exception ex) {
ex.printStackTrace();
}
I'm able to print out the data type of the value along with the value itself. All the values are part of class java.util.LinkedHashMap$Entry. I'm not able to cast the values to a String to add them to an ArrayList. How should I go about doing this? Thanks
From the jackson-databind documentation you can convert your json to a Map<String, Object> map with the following line (you have boolean, list, number and string values in your json) :
Map<String, Object> map = mapper.readValue(json, Map.class);
// it prints {meta={stock=AWS, date modified=90}, roles=[Member, Admin], name=John Doe, admin=true, email=john.doe#example.com}
System.out.println(map);
If you want to save your map values string representation into an ArrayList data you can iterate over them with a loop :
List<String> data = new ArrayList<>();
for (Object value : map.values()) {
data.add(value.toString());
}
//it will print [{stock=AWS, date modified=90}, [Member, Admin], John Doe, true, john.doe#example.com]
System.out.println(data);
Your data type of entries will be like:
meta: Map<String:Object>
roles: List<String>
admin: Boolean
So you will get an exception when casting to string for each entry value.
You should handle different data type and convert it according to your request:
Object value = entry.getValue();
I highly recommend you write more few functions to check and convert map/list/primitive variables to expected data (String):
boolean isList(Object obj);
boolean isMap(Object obj);
...
public List<String> convertMap(Map<String,Object> map);
...

Counting occurrences of a unique element in ArrayList

So currently I have a
static List<List<String>> lines = new ArrayList<>();
with the Arraylist containing values such as
{["ID", "Last Name", "First Name", "Vaccine Type", "Vaccination Date", "Vaccine Location"]
["12345", "Doe", "John", "Pfizer", "10/30/2020", "Argentina"]
["54321", "Adam", "Marceline", "Pfizer", "11/19/2020", "Russia"]
["70513", "Sitz", "Tomislav", "Moderna", "12/2/2020", "England"]
["54371", "Lyndon", "Sergei", "Johnson&Johnson", "03/01/2021", "Israel"]
["41027", "Chambers", "Wallis", "Moderna", "01/28/2021", "United States"]
}
I want to find the number of unique vaccine types as well as find the frequency of it. So for example this arraylist should return something like
"Pfizer:2, Moderna:2, J&J:1"
ideally in it's own seperate data structure(array).
I tried using a HashList but the way my arraylist is formatted is not supported.
Set<String> unique = new HashList<String>(lines);
for (String key : unique) {
System.out.println(key + ": " + Collections.frequency(lines, key));
}
I get the error "the hashlist cannot be resolved to type".
Map<String,Integer> map = new HashMap<>();
for(list<String> l : lines) {
String name = l.get(3);
int count = map.getOrDefault(name,0);
count++;
map.put(name,count)
}
//now iterate the map and print all the values
Map<String, Long> result = lines.stream().collect(Collectors.groupingBy(list -> list.get(3), Collectors.counting()));
produces: // {Pfizer=2, Moderna=2, Johnson&Johnson=1}
A cleaner way would have been to map each list of strings into a corresponding object and then stream through those, but that is for you to refactor :)

Map dynamic nested Json object to hashmap and store keys and values into two string variable with comma separated

I need to map dynamimc json nested object into hashmap I could come up with solution but I couldn't get expected output.
Here is code
HashMap<String, Object> map = new Gson().fromJson(dynamicJson, HashMap.class);
String keys = map.keySet().stream().collect(Collectors.joining(", "));
String values = map.values().stream().map(obj -> String.valueOf(obj)).collect(Collectors.joining(", "));
System.out.println("Keys: " + keys);
System.out.println("Values: " + values);
Sample Json
{
"name": "Notification 2",
"message": "Facebook",
"tags":[
{
"city" : "Matara",
"village" : "Mirissa"
}
]
}
Actual output :
name, message, tags Notification 2, Facebook, [{city=Matara,
village=Mirissa}]
Expected output
name, message, tags/city, tag/village
Notification 2, Facebook, Matara, Mirissa
In above logic you are not processing sub elements, check below code
HashMap<String, Object> map = new Gson().fromJson(dynamicJson, HashMap.class);
Map<String, String> keyValueMap = new HashMap<>();
map.forEach((key, value) -> {
if (value instanceof List) {
((List)value).stream().forEach(obj -> { // processing sub elements
if (obj instanceof Map) {
((Map)obj).forEach((k,v) -> {
keyValueMap.put(key+"/"+k, v.toString());
});
}
});
} else { // direct value, no subelement
keyValueMap.put(key, value.toString());
}
});
The above logic will work for only elements which are inside List, so you need modify above logic little more generic based on your input json structure.
Below logic is to print the data which can be optimzed , i have written below logic so that it will be easy to understand
keyValueMap.forEach((k, v) -> {
System.out.print(k+ ",");
});
System.out.println();
keyValueMap.forEach((k, v) -> {
System.out.print(v+ ",");
});
it will give out put as below
name,tags/city,message,tags/village,
Notification 2,Matara,Facebook,Mirissa,
Thanks
Prasad

Java: Extract index src from multiarray

So, I'm encountering this weird problem: I'm using the Woocommerce Rest API and I need to get the src from the "images"-array.
I'v already tried to save the images-array in an other array, but then I have no idea how to get the "src" from the array:
try {
ConnectionRequest r = new ConnectionRequest();
r.setPost(false);
r.setUrl("https://" + tokens.getShop_name_token() + ".ch/wp-json/wc/v3/products?consumer_key=" + tokens.getConsumer_key_token() + "&consumer_secret=" + tokens.getSecret_key_token());
NetworkManager.getInstance().addToQueueAndWait(r);
Map<String, Object> result = new JSONParser().parseJSON(new InputStreamReader(new ByteArrayInputStream(r.getResponseData()), "UTF-8"));
//JSON Filter
ArrayList<Map<String, String>> myList = (ArrayList<Map<String, String>>) result.get("root");
for (int i = 0; i < myList.size(); i++) {
Map<String, String> dtls = myList.get(i);
productsArr.add(dtls.get("name"));
productStock.add(dtls.get("stock_status"));
productDateCreated.add(dtls.get("date_created"));
//TODO: Filter out image-soure
productImages.add(dtls.get("images"));
}
System.out.println(productImages);
Output: [[], [], [], [{id=16.0, date_created=2018-11-08T15:21:14,
date_created_gmt=2018-11-08T15:21:14,
date_modified=2018-11-08T15:21:14,
date_modified_gmt=2018-11-08T15:21:14,
src=https://website.com/wp-content/uploads/2018/11/1.jpg, name=Vneck
Tshirt, alt=}],
[{id=15.0, date_created=2018-11-08T15:21:14, date_created_gmt=2018-11-08T15:21:14,
date_modified=2018-11-08T15:21:14,
date_modified_gmt=2018-11-08T15:21:14,
src=https://website.com/wp-content/uploads/2018/11/21.jpg,
name=Tshirt, alt=}]]
I got this far. Now my question is: How can I filter out the index to get the "src" of the image?
As you use the rather minimally-featured com.codename1.io.JSONParser JSON parser, which parses JSON to a Map<String, Object> and nothing else, then what you want to do is convert the Object that you get selecting a value to the expected type, and repeat from there.
If the top-level JSON object is an array, then a special "root" element is created, which is what you are getting here. That means that the structure of your JSON is parsed as this:
{
"root": [
{
"name": <str>,
"stock_status": <???>,
"date_created": <str>,
"images":
{
"id": <num>,
"date_*": <str>,
"src": <str>,
"name": <str>,
"alt": <str>
}
]
}
]
}
So, to extract an image's src, you have extracted the "root" array and iterated over it. Instead of casting the results to Map<String, String> however, you want to keep them as Map<String, Object>:
for (const Map<String, Object> element : (List<Map<String, Object>>) result.get("root")) {
// The "element" object has an "images" value that is a list of objects
for (const Map<String, Object> image : (List<Map<String, Object>>) element.get("images")) {
// Save the "src" field of each image
productImages.add((String) image.get("src"));
}
}

NullPointer exception while parsing JSON Map in java

I'm trying to parse productId, name, and price from my below JSON in the REST API - but I'm getting null pointer exception when I try to get he name - String name = (String) obj.get("name");, may I know what I'm doing wrong here?
Any help would be really appreciated.
Thanks!
JSON:
{
"id": "af0b86eb-046c-4400-8bc4-0e26042b8f53",
"products": [{
"productId": "1234",
"name": "apple",
"price": "383939"
}
]
}
Controller.java
public ResponseEntity<Object> create(#RequestBody Map<String, Object> obj) {
Product response = myservice.create(obj);
return new ResponseEntity<Object>(response, HttpStatus.CREATED);
}
Service.java
public Product create(Map<String, Object> obj) {
for (Entry<String, Object> entry : obj.entrySet()) {
System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());
}
Object [] products = (Object[]) obj.get("products");
HashMap <String, Object> productOne = (HashMap) products[0];
String productId = (String) productOne.get("name");
System.out.println("productId: " +productId);
String name = (String) obj.get("name");
System.out.println("name: " +name);
}
Output:
Key : products Value : [{productId=1234, name=apple, price=383939}]
By obj.get("name"), you try getting value by key name from a top-level of your json request, while it's a property of a second-level object
In pseudo-code (skipping casting and null-checks) it should look like this:
obj.get("products")[0].get("name")
In Service.java you print obj inside for loop. Your print says that key is products and value is an array of objects.
So in following line obj is that top-level object and not contains “name” field.
String name = (String) obj.get("name");
System.out.println("name: " +name);
What if you call obj.get(“products”) and try to cast it into a collection? Then trying to fetch the first index from the collection. It should contain the inner object which contains name key and value.
You should reason exactly as you see the json, by depth(or level).
Initially the whole json is contained in the obj map which contains two key-value pairs:
(key = "id", value = "af0b86eb-046c-4400-8bc4-0e26042b8f53")
(key = "products", value = [{"productId": "1234", "name": "apple", "price": "383939"}])
Since you are interested in product details, the first step is two extract the array products like this:
Object [] products = obj.get("products");
Now product is an array of objects. Since you know that your objects are in turn hash maps you can cast each object to a map and access the key(s) that you want:
HashMap <String, Object> productOne = (HashMap) products[0];
String productId = (String) productOne.get("productId");
String name = (String) productOne.get("name");
..

Categories

Resources