How can i get json indexes as keys? - java

The user of the api sends a json like this:
{ "0": "3♥", "1": "5♣", "2": "4♣",“3”: “9♥”, … }
im trying to save the the value of each index (3♥,5♣,4♣,9♥) in a list.
all I have now is the POST method but I dont know how to read it) OR i don't know if i need to use another type of request
#RequestMapping(value="/start", method = RequestMethod.POST, consumes= "application/json" )
public String getData(#RequestBody ?? ) { }
thank you in advance

Try below
#RequestMapping(value="/start", method = RequestMethod.POST, consumes= "application/json" )
public String getData(#RequestBody HashMap<String, String> data) {
List<String> result = new ArrayList<>();
for (String val: data.values()){
result.add(val);
}
}
We are storing the user input into a HashMap and then extracting its values in the for loop. You can ofcourse collect the data returned by data.values() into an ArrayList or any collection of your choice to avoid the for loop.
You can use EntrySet if you need both key and value like below
for (Map.Entry<String, String> entry : data.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
// ...
}

Try this:
#PostMapping("/saveData")
public ResponseEntity<String> saveData(#RequestBody Map<Integer, Object> data) {
List<Object> values = new ArrayList<>();
data.forEach(values::add);
//Additonal code here, e.g. save
return ResponseEntity.ok().build();
}
#RequestBody Map<Integer, Object> ensures that indexes will always be Integers. Value type can be changed to String.
If indexes are not int, 400 Bad Request will be returned. Indexes must be positive integers.
You can also user longer notation for adding elements to the list (might be more clear):
data.forEach((key, value) -> values.add(key, value));
For this payload:
{
"0": "3♥",
"1": "5♣",
"2": "4♣",
"3": "9♥"
}
That's the outcome:

Related

Passing JSON keys as String containing a range of numbers

I am trying to have a set of keys to point to a value.
For example the key 0 is to point to the value "EXAMPLE_1"
keys 1,2,3,4,5 is to point to the value "EXAMPLE_2"
and keys 6,7,8,9,10 is to point to the value "EXAMPLE_3"
This is the JSON structure I came up with (which will exist in an external file).
{
"0" : "EXAMPLE_1",
"1,5" : "EXAMPLE_2",
"6,10" : "EXAMPLE_3"
}
Using following code to read and fetch correct value.
private String getValue(String count){
Map<String, String> map = // code to fetch data from the file and get above map. Works.
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
String[] keysInRange = key.split(",");
if(Arrays.asList(keysInRange).contains(count)){
return value;
}
}
}
This technically works but is there a better way to do this.
Looking to improve the JSON structure.
Finding it silly to be passing in the keys in this manner.
Note that the keys would be a single number or always in a range.
You could try below. This is assuming, Keys in range are like this 1,2,3,4,5 for 1,5
private String getValue(String count){
Map<String, String> map = // code to fetch data from the file and get above map. Works.
If(map.containsKey(count)){
return map.get(count);
}
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if(key.contains(","+count) || key.contains(","+count+",") || key.contains(count+",") ){
return value;
}
}
}
You could change your JSON structure to an array of elements:
{[ {
"name": "EXAMPLE_1",
"from": "0",
"to": "0"
},
{
"name": "EXAMPLE_2",
"from": "1",
"to": "5"
},
{
"name": "EXAMPLE_3",
"from": "6",
"to": "10"
}
]}
and parse them with a JSON parser like Jackson oder GSON in data objects like
class Example {
private String name;
private int from;
private int to;
// ommitted getters & setters for brevity
}
Your method then becomes (using Java 8+ and the streams api):
private String getValue(int count) {
Set<Example> examples = ... // code to fetch data from the file
Optional<Example> match = examples.stream()
.filter(example -> example.getFrom() >= count)
.filter(example -> example.getTo() <= count)
.findFirst();
// or return the Optional<Example> directly
return match.map(Example::getValue).orElse(null);
}

Java 8 Streams hashmap

I need perform an hashmap iteration using Java 8 streams. I need to iterate over an hashmap. Check whether a particular key ("new") does not have null or empty values, copy that value to a variable (String val1) of type string. Then again check for another key for ex:"old" and then copy that value to a variable (String val2) of type string and call the main method where i need to send these 2 values (val1, val2). This has to be done with in hashmap iteration. Can you please help me on this.
The code:
map1.entrySet()
.stream()
.filter(s -> {
if (s.getKey().contains("abc") && !s.getValue().equals("") && s.getValue()!=null) {
String val1 = s.getValue;
if (s.getKey().contains("bb")) {
String val2 = s.getValue(); //call the function
callFunction(val1,val2);
}
}
else {
}
});
Need to be done using Java 8
for(Map.Entry e : map1.entrySet()) {
if(e.containsKey("new")&& !e.getValue().equals("")){
String val1 = (String) e.getValue();
if(e.containsKey("old")&& !e.getValue().equals("")){
String val2 = (String) e.getValue();
//call the function-- This is boolean
if(validateMethod(val1, val2)){ // if true
Map<String, String> map2 = new HashMap<>();
map2.putAll(e);
}
}
}
}
You need to look for particular keys : new and old so you don't need to iterate over the entries of the map, because if the keys exist they will be unique.
get the value of the specific keys, if they don't exist, keep en empty String
do your stuff with these values
Map<String, String> map1 = ...;
String v1 = map1.getOrDefault("new", "");
String v2 = map1.getOrDefault("old", "");
Map<String, String> map2 = new HashMap<>();
if(!v1.isEmpty() && !v2.isEmpty() && validateMethod(v1, v2)){
// do your stuff
}
You might put the check for isEmpty in your validateMethod rather than in an if
Try it with this:
yourMap.entrySet().stream()
From this point, you can manage. Stream consists of Entry<Key,Value> so you can check whatever you want to.

How to convert a Map to Arraylist of Objects?

Suppose I have having Json response like this:
{
"status": true,
"data": {
"29": "Hardik sheth",
"30": "Kavit Gosvami"
}
}
I am using Retrofit to parse Json response. As per this answer I will have to use Map<String, String> which will give all the data in Map. Now what I want is ArrayList<PojoObject>.
PojoObject.class
public class PojoObject {
private String mapKey, mapValue;
public String getMapKey() {
return mapKey;
}
public void setMapKey(String mapKey) {
this.mapKey = mapKey;
}
public String getMapValue() {
return mapValue;
}
public void setMapValue(String mapValue) {
this.mapValue = mapValue;
}
}
What is the best way to convert a Map<key,value> to a List<PojoObject>?
If you can expand your class to have a constructor taking the values as well:
map.entrySet()
.stream()
.map(e -> new PojoObject(e.getKey(), e.getValue()))
.collect(Collectors.toList());
If you can't:
map.entrySet()
.stream()
.map(e -> {
PojoObject po = new PojoObject();
po.setMapKey(e.getKey());
po.setMapValue(e.getValue());
return po;
}).collect(Collectors.toList());
Note that this uses Java 8 Stream API.
Looks like Java has exact POJO Map.Entry like you want. Hence, you can extract the entry set from map and iterate over the entry set like below or you can further convert the set to list like in next snippet and continue with your processing.
//fetch entry set from map
Set<Entry<String, String>> set = map.entrySet();
for(Entry<String, String> entry: set) {
System.out.println(entry.getKey() +"," + entry.getValue());
}
//convert set to list
List<Entry<String, String>> list = new ArrayList(set);
for(Entry<String, String> entry: list) {
System.out.println(entry.getKey() +"," + entry.getValue());
}
Try this
List<Value> list = new ArrayList<Value>(map.values());
Or
hashMap.keySet().toArray(); // returns an array of keys
hashMap.values().toArray(); // returns an array of values
Should be noted that the ordering of both arrays may not be the same.
or
hashMap.entrySet().toArray();
You can use this method to convert map to list
List<PojoObject> list = new ArrayList<PojoObject>(map.values());
Assuming:
Map <Key,Value> map;
ArrayList<Map<String,String>> list = new ArrayList<Map<String,String>>();
this may be the best way.

Convert Multi value Map to CSV

How do we convert multi value map to CSV, i am able to do with the single key - value map. But facing issue with multi value map.
I do convert key value using this
private String getCSVRow(Set<String> headers, Map<String, String> map) {
List<String> items = new ArrayList<String>();
for (String header : headers) {
String value = map.get(header) == null ? "" : map.get(header).replace(",", "");
items.add(value);
}
return StringUtils.join(items.toArray(), ",");
}
In this if i want to put Map<String, List<String>> as i parameter how will i do it?
create a method that will convert List to String, and call that method from the for loop. So your code becomes
for (String header : headers) {
String value = map.get(header) == null ? "" : generateStringFromList(map.get(header));
items.add(value);
}
private String generateStringFromList(List<String> list) {
// create the code here
}

How to compare arraylist with Hasmap and get the key from Hashmap based on value?

I've got list :
ArrayList<String> list = new ArrayList<>();
and map :
Map<String, List<String>> map = new HashMap<>();
I need to compare values of the list and map and return key based on that value
The problem is that I dont know how to synchronize iterations as arraylist has smaller size as each list in map.
Also I tried this method :
public static Object getKeyByValue(Map<String,List<String>> map, String value) {
for (Entry<String, List<String>> entry : map.entrySet()) {
if (Objects.equals(value, entry.getValue())) {
return entry.getKey();
}
}
return null;
}
getKeyByValue(map,list.get(0));
..but this call retuned false even If there is certain value...
Any ideas how get each key for each value?
Thank you very much
You are comparing a List<String> to a String, so it would never return true.
Use List.contains instead, to determine if the String appears in the List :
if (entry.getValue().contains(value)) {
return entry.getKey();
}

Categories