I'm looking for a way to get the values for just a specific key when I get into the second loop here. I'm using snakeyaml and loading it to a Map. My yaml looks something like this:
number:
id: status.number
label: Number
contactType:
id: status.contact_type
label: Contact Type
What I'm attempting to do is just get the key and value for id. It's probably super obvious, but I haven't found a way to do so.
Map<String, Map<String, String>> a = (Map<String, Map<String, String>>) yaml.load(input);
for (Map.Entry<String, Map<String, String>> t : a.entrySet()) {
String key = t.getKey();
for (Map.Entry<String, String> e : t.getValue().entrySet()) {
System.out.println("OuterKey: " + key + " InnerKey: " + e.getKey() + " VALUE:" + e.getValue());
}
}
To get the value(s) for the "inner key", you don't need to loop through every inner map.
In the following example, I assume you already have an innerKey variable that holds the desired inner key.
Map<String, Map<String, String>> a = (Map<String, Map<String, String>>) yaml.load(input);
for (Map.Entry<String, Map<String, String>> t : a.entrySet()) {
String outerKey = t.getKey();
String innerValue = t.getValue().get(innerKey);
System.out.println("OuterKey: " + outerKey + " InnerKey: " + innerKey + " VALUE:" + innerValue);
}
Related
I am new to Java. I have a problem that, I need to Implement the decode(String) method that decodes a String to a corresponding Map. In the assignment, the requirements are like this,
Empty keys and values are allowed, but the equals sign must be present (e.g. "=value", "key=").
If the key or value is empty, empty String should be returned.
If the given String is empty, an empty Map should be returned.
If the given String is null, null should be returned.
Sample Input: one=1&two=2
Should return a Map containing {"one": "1", "two": "2"}
Map<String, String> map = new HashMap<>();
map.put("One", "1");
map.put("Two", "2");
map.put("", "");
map.put("Key", "");
map.put("", "Value");
Set<String> keys = map.keySet();
for(String key : keys) {
System.out.print("\"" + key + "\"" + ":" + "\"" + map.get(key) + "\"");
}
My piece of code is giving output as required, But I have implemented this in the main method with Map<K, V> interface, while I need to write code that takes String as a parameter and decodes to Map.
Thanks
One solution could be:
public Map<String, String> parseMap(String mapString) {
if (mapString == null || mapString.isEmpty()) {
return Collections.emptyMap();
}
return Arrays.stream(mapString.split("&"))
.map(this::splitParam)
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
}
public AbstractMap.SimpleEntry<String, String> splitParam(String it) {
final int idx = it.indexOf("=");
final String key = it.substring(0, idx);
final String value = it.substring(idx + 1);
return new AbstractMap.SimpleEntry<>(key, value);
}
usage
String inputString = "one=1&two=2";
Map<String, String> map = parseMap(inputString);
//your code to print the map again
Set<String> keys = map.keySet();
for(String key : keys) {
System.out.print("\"" + key + "\"" + ":" + "\"" + map.get(key) + "\"");
}
try this in your editor, just 4 lines :)
String input = "one=1&two=2";
String[] kvs = input.split("&");
Map<String, String> hashMap = Stream.of(kvs)
.collect(Collectors.toMap(item -> item.split("=")[0],
item -> item.split("=")[1]));
hashMap.forEach((k, v) -> System.out.println(k + ":" + v));
I have a string object representing a json object returning for a network task. I need to convert it into a Map (or HashMap). I've been using gson, but it has been unsuccessful. Here is the json string (please excuse indentation, for I had to manually add newline spaces):
{
"plans":{
"Ankle Recovery":{
"StartDate":"09/24/2018",
"Progress":0.6666666666666666,
"Tasks":[
{
"date":"10/16/2018",
"amount":200,
"task":"ice ankle for 30 min",
"completed":true,
"requirementType":"steps"},
{
"date":"10/17/2018",
"amount":200,
"task":"ice ankle for 30 min",
"completed":true,
"requirementType":"steps"
},
{
"date":"10/18/2018",
"amount":200,
"task":"ice ankle for 30 min",
"completed":false,
"requirementType":"steps"
}
],
"Username":"email#site.com",
"Doctor":"Mike Michaels",
"EndDate":"12/24/2018"}},
"status":true
}
This is the code I've been using to make the transformation:
private Map<String, String> plans;
plans = new Gson().fromJson(result, new TypeToken<Map<String, String>>() {}.getType());
Neither nor has worked. I've tried some different solutions across Stack Overflow, but none yield success to this point.
I'm also getting an exception thrown that I don't quite understand:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 11
(Column 11 is just before the first quote in "AnkleRecovery")
I'd like to use simple gson to make this work if possible. But I'm open to alternative solutions.
The JSON you posted is not valid, line 3:
"Ankle Recovery" : {
// / \
// this is what you are missing
This tool will help you verify the JSON structure and format it as well: https://jsonlint.com/
Now to the actual problem. Your JSON has a following structure:
{
"plans": Object,
"status": Boolean,
}
Neither of these are strings ( object != string, boolean != string ).
Such a structure can not be mapped to Map<String, String> as this requires the value to be a string.
You will need to create multiple POJOs to define your structure and then map to these, e.g.:
class Project {
public Map<String,Plan> plans;
public Boolean status;
}
class Plan {
public String StartDate;
public Double Progress;
public List<Task> tasks;
...
}
class Task {
...
}
Disclaimer...
I would always investigate using one or more POJOs which can be used to represent the data structure if at all possible.
Without more information, it's impossible to know if keys like Ankle Recovery are stable or not, or if they might change.
"A" possible solution
Generally, JSON is in the form of key/value pairs, where the value might be another JSON object, array or list of other values, so you "could" process the structure directly, for example...
String text = "{\n"
+ " \"plans\":{\n"
+ " \"Ankle Recovery\":{\n"
+ " \"StartDate\":\"09/24/2018\",\n"
+ " \"Progress\":0.6666666666666666,\n"
+ " \"Tasks\":[\n"
+ " {\n"
+ " \"date\":\"10/16/2018\",\n"
+ " \"amount\":200,\n"
+ " \"task\":\"ice ankle for 30 min\",\n"
+ " \"completed\":true,\n"
+ " \"requirementType\":\"steps\"\n"
+ " },\n"
+ " {\n"
+ " \"date\":\"10/17/2018\",\n"
+ " \"amount\":200,\n"
+ " \"task\":\"ice ankle for 30 min\",\n"
+ " \"completed\":true,\n"
+ " \"requirementType\":\"steps\"\n"
+ " },\n"
+ " {\n"
+ " \"date\":\"10/18/2018\",\n"
+ " \"amount\":200,\n"
+ " \"task\":\"ice ankle for 30 min\",\n"
+ " \"completed\":false,\n"
+ " \"requirementType\":\"steps\"\n"
+ " }\n"
+ " ],\n"
+ " \"Username\":\"email#site.com\",\n"
+ " \"Doctor\":\"Mike Michaels\",\n"
+ " \"EndDate\":\"12/24/2018\"\n"
+ " }\n"
+ " },\n"
+ " \"status\":true\n"
+ "}";
Gson gson = new Gson();
Map<String, Object> fromJson = gson.fromJson(text, Map.class);
Map<String, Object> plans = (Map<String, Object>) fromJson.get("plans");
Map<String, Object> recovery = (Map<String, Object>) plans.get("Ankle Recovery");
List<Map<String, Object>> tasks = (List<Map<String, Object>>) recovery.get("Tasks");
for (Map<String, Object> taks : tasks) {
for (Map.Entry<String, Object> entry : taks.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}
Now, this would get you the output of ...
date = 10/16/2018
amount = 200.0
task = ice ankle for 30 min
completed = true
requirementType = steps
date = 10/17/2018
amount = 200.0
task = ice ankle for 30 min
completed = true
requirementType = steps
date = 10/18/2018
amount = 200.0
task = ice ankle for 30 min
completed = false
requirementType = steps
Having said all that, your own parsing might be a lot more involved, have to inspect if certain keys exist or not and taking appropriate action as required
I have a Map :
Map<String, String> value
How to obtain particular value "String" ----> "type" from json value, how do i obtain it?
I tried below code, which only returns me KEY and not VALUE
Iterator it = payload.entrySet().iterator();
while (it.hasNext())
{
Map.Entry pair = (Map.Entry)it.next();
System.out.println(pair.getKey() + " = " + pair.getValue());
String key = pair.getKey().toString();
String value = pair.getValue().toString();
Log.d("getActionValue", "key : " + key);
Log.d("getActionValue", "value : + value");
}
You don't access your variable in your output, since value is still in in the string.
Change like this:
Log.d("getActionValue", "value : " + value);
Your problem is here Log.d("getActionValue", "value : + value"); it should be Log.d("getActionValue", "value : "+ value);
Try this for loop :-
for (Map.Entry<String, String> entry : payload.entrySet())
{
Log.d("getActionValue", "key : " + entry.getKey());
Log.d("getActionValue", "value :" + entry.getValue());
}
I want that particular "String" ----> "type" from value, how do i
obtain it?
payload Map contains JSONObject's as value of every key. so to get type need to first convert String to JSONObject then get value using type key:
JSONObject jsonObject=new JSONObject(value);
String strType="";
if(jsonObject.has("notification-action")){
JSONObject jsonObjectnotification=jsonObject.optJSONObject
(""notification-action"");
if(jsonObjectnotification.has("type")){
strType=jsonObjectnotification.optString("type");
}
}
You logging it wrong.
Should be:
Log.d("getActionValue", "value : " + value);
HashMap<String, List<String>> filterableMap = new HashMap<>();
filterableMap.put("department", Arrays.asList("A","B",null));
filterableMap.put("group", Arrays.asList("C","D",null));
From the above map i need to dynamically build a queryString like show below.
"SomeURL"/token/filter?department=A&department=B&group=C&group=D
I just used Hashmap we can use any thing as long as we can hold the values in name value pair.
for (Map.Entry<String, List<String>> entry : filterableMap.entrySet()) {
String key = entry.getKey();
List<String> value = entry.getValue();
for(String aString : value){
System.out.println("key : " + key + " value : " + aString);
if("department".equalsIgnoreCase(key)) {
qStrBulderBuilder.append("department =");
qStrBulderBuilder.append(value);
}
}
}
I am using like above approach , but i need to make sure i need put "=" and "&" in the right places some times we may not get "department" or "group"
I have a nested hashmap (Hashmap inside a hashmap).
Map<String,Map<String,String>> test = new HashMap<String,Map<String,String>>();
Map<String,String> testMp = new HashMap<String,String>();
testMp.put("1", "Key1");
testMp.put("2", "Key2");
testMp.put("3", "Key3");
testMp.put("4", "Key4");
testMp.put("5", "Key4");
test.put("One", testMp);
Ideally if I need to print the key and the values in the test map, I'd do this -
for(Map.Entry<String, Map<String,String>> t:test.entrySet()) {
System.out.println("KEY: " +t.getKey()+ " VALUE:" +t.getValue());
}
But I want the key and the value of the inner map as well. I want something like this -
Key of outermap
Key of innermap, and its value.
Then do a nested loop :
for(Map.Entry<String, Map<String,String>> t:test.entrySet()) {
String key = t.getKey();
for (Map.Entry<String,String> e : t.getValue().entrySet())
System.out.println("OuterKey: " + key + " InnerKey: " + e.getKey()+ " VALUE:" +e.getValue());
}
or
for(Map.Entry<String, Map<String,String>> t:test.entrySet()) {
System.out.println(t.getKey());
for (Map.Entry<String,String> e : t.getValue().entrySet())
System.out.println("KEY: " + e.getKey()+ " VALUE:" +e.getValue());
}
Write a recursive method which will call itself when it encounters that the entry to corresponding key is a map.