I have the following data stored as an Object.
{
"data": {
"name": "name",
"titles": [
[
"valueOne",
"valueTwo"
],
[
"somethingElse"
],
[
"anotherValue",
"someValue"
],
[
"myValue"
],
[
"aValue",
"theValue"
]
]
},
}
What would be the cleanest way to convert all the values from camel case to snake case?
Meaning change valueOne to value_one and so on.
Was trying to use ObjectMapper but looks like it is only for use for keys, not values.
Tried the following. But end up with no diff or incorrect structure. Pls help.
// makes no difference when this is done.
Map<String, Object> myLayout = (Map<String, Object>) data.getMyLayout();
List<List<String>> titles = (List<List<String>>) myLayout.get("titles");
titles.forEach(titleList -> titleList.forEach(title -> CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, title)));
// this changes the structure incorrectly. Should maintain list of list of String.
Map<String, Object> myLayout = (Map<String, Object>) data.getMyLayout();
List<List<String>> titles = (List<List<String>>) myLayout.get("titles");
List<String> updatedTitles = titles.stream()
.flatMap(title -> title.stream()
.map(name -> CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, name))
).collect(Collectors.toList());
myLayout.put("titles", updatedTitles);
Incorrect structure based on above implementation.
"myLayout": {
"name": "name",
"titles": [
"value_one",
"value_two",
"something_else",
"another_value",
"some_value",
"my_value",
"a_value",
"the_value"
]
},
Ultimately looking to achieve this.
{
"data": {
"name": "name",
"titles": [
[
"value_one",
"value_two"
],
[
"something_else"
],
[
"another_value",
"some_value"
],
[
"my_value"
],
[
"a_value",
"the_value"
]
]
},
}
Solved it by performing the following, using a map instead of flatmap and collecting the internal mapped data first before collecting the outer list.
Map<String, Object> myLayout = (Map<String, Object>) data.getMyLayout();
List<List<String>> titles = (List<List<String>>) myLayout.get("titles");
List<String> updatedTitles = titles.stream()
.map(title -> title.stream()
.map(name -> CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, name))
.collect(Collectors.toList())
).collect(Collectors.toList());
myLayout.put("titles", updatedTitles);
Related
I have a data that looks like so:
{
"name":{
"first": "<firstName>",
"last": "<lastName>"
},
"info": "<info>",
"place":{
"location": "<location>",
},
"test": "<test>"
}
However, I want to customize the Response json and group the data by the location.
In other words I would like to have a response like this:
"location":[{
"name": <location>,
user: [{
"name": <firstName> + <lastName>,
"info": <info>,
"test": <test>
}]
}]
I have tried to the it into a map like so:
List<Data> data= newArrayList(repository.findAll(Sort.by(Sort.Direction.ASC, "location")));
Map<String, Object> result= new HashMap<>();
for (Data d : data) {
result.put("name", d.getLocation());
result.put("user", d.getFirstName());
...
and so on, but this does not work. What is the best approach to achieve my desired result?
As of now you have a single result map, which you are then overwriting in the loop, so it will contain data for a location only, the last one. What you probably wanted to do is creating a list of those maps, which requires creating a new map inside the loop, and collecting them in a list:
List<Map<String, Object>> result=new ArrayList<>();
for(Data d : data) {
Map<String, Object> item = new HashMap<>();
item.put("name", d.getLocation());
item.put("user", d.getFirstName());
...
result.add(item);
}
I need to get the common elements from List<Map<String,Object>> and print that result. Below is the example where the result would be some json.
Ex:
[
{
"Id" : "123",
"common" : [
{
"group":"abc",
"department" : "xyz"
},
{
"group":"abc",
"department" : "zyx"
}
]
]
Depends what the type of Object
List<Map<String,Object>> o = ...
Object common = o.get(0).get("common");
// if object is of type Map<String, String>
Map<String,Object> data = (Map<String,Object>) common;
I have 2 lists, the 1st list contains a field that can be duplicated and seconds list contain the same field without duplicate with other fields. What I need is to join the two list to one based on that common field.
List 1 :
[
{
"id" : "1"
"name : "hello",
"item_name": "Name"
},
{
"id" : "1"
"name : "hi"
"item_name": "Name2"
},
{
"id" : "2"
"name : "hello"
"item_name": "Name"
}
]
Second List :
[{
"id" : "1"
"age" : "10",
"place" : "0",
"date" : "0"
},
{
"id" : "2"
"age" : "12",
"place" : "1",
"date" : "0
}]
Expected Result :
[
{
"id" : "1"
"name : "hello",
"item_name": "Name",
**"age" : "10",
"place" : "0",
"date" : "0**
},
{
"id" : "1"
"name : "hi"
"item_name": "Name2"
**"age" : "10",
"place" : "0",
"date" : "0"**
},
{
"id" : "2"
"name : "hello"
"item_name": "Name"
**"age" : "12",
"place" : "1",
"date" : "0"**
}
]
Bold areas are joined from the second list
Please help in this
I have tried :
Map<String, String> listMap = list2
.stream()
.collect(Collectors.toMap(List1Entity::getId,
List1Entity::getId));
list1.forEach(a -> {
a.setPlace(listMap.get(a.getId()));
});
But getting error at .collect(),
no instances or type variable exist so that List2Entity conforms to
List1Entity
Did you mean List2Entity in the first statement?
Map<String, String> listMap = list2
.stream()
.collect(Collectors.toMap(List2Entity::getId,
List2Entity::getPlace));
Your requirements are a bit unclear when it comes to define the joining part between the two lists.
You can start with something like this and adapt mapFunction to your needs.
String list1 = "[{\"id\":\"1\",\"name\":\"hello\",\"item_name\":\"Name\"},{\"id\":\"1\",\"name\":\"hi\",\"item_name\":\"Name2\"},{\"id\":\"2\",\"name\":\"hello\",\"item_name\":\"Name\"}]";
String list2 = "[{\"id\":\"1\",\"age\":\"10\",\"place\":\"0\",\"date\":\"0\"},{\"id\":\"2\",\"age\":\"12\",\"place\":\"1\",\"date\":\"0\"}]";
ObjectMapper mapper = new ObjectMapper();
List<Map<String, Object>> l1 = mapper.readValue(list1, new TypeReference<List<Map<String, Object>>>(){});
List<Map<String, Object>> l2 = mapper.readValue(list2, new TypeReference<List<Map<String, Object>>>(){});
final UnaryOperator<Map<String, Object>> mapFunction = map -> {
final String id = map.get("id").toString();
l2.stream()
.filter(map2 -> map2.get("id").toString().equals(id))
.findAny()
.ifPresent(map::putAll);
return map;
};
List<Map<String, Object>> result = l1
.stream()
.map(mapFunction)
.collect(Collectors.toList());
I've got this json object
{
"type" : "employee",
"columns" :
[
{
"id" : 1,
"human" :
[
{
"name" : "ANA",
"age" : "23"
},
{
"name" : "IULIA",
"age" : "22"
}
]
},
{
"id" : 2,
"human" :
[
{
"name" : "ADI",
"age" : "21"
},
{
"name" : "GELU",
"age" : "18"
}
]
}
]
}
and I need to extract the first name from each human list.
I've tried .body("columns.human.name[0]", everyItem(containsString("A"))) but it doesn't work. Any ideas?
Using JsonPath you can get all columns and all humans.
Each of JSON Object is represented as HashMap<>. If it contains only fields it's HashMap<String, String> but if contains arrays or nested JSON Objects then it is HashMap<String, Object> where Object is either another JSON Object or array.
Given the above you can use following code to get all columns and name of first human in each column:
JsonPath path = response.jsonPath();
List<HashMap<String, Object>> columns = path.getList("columns");
for (HashMap<String, Object> singleColumn : columns) {
List<HashMap<String, Object>> humans = (List<HashMap<String, Object>>) singleColumn.get("human");
System.out.println(humans.get(0).get("name"));
}
The above code will print ANA and ADI in the console.
You can store the results in List<String> for further processing
you can get all "name" from humans with jsonPath : $.columns[*].human[*].name it will give below result :
[
"ANA",
"IULIA",
"ADI",
"GELU"
]
And if you want only first "name" then you need to use josn : $.columns[*].human[0].name this will give you below result:
[
"ANA",
"ADI"
]
I am working on a project where I get a JSON response from my API using entities and DTO
Folowing is the response:
return XXXResponseDTO
.builder()
.codeTypeList(commonCodeDetailList)
.build();
commonCodeDetailList list contains the data from the database. Final output will be
{
"code_type_list": [
{
"code_type": "RECEIVING_LIST",
"code_list": [
{
"code": "1",
"code_name": "NAME"
},
{
"code": "2",
"code_name": "NAME1"
}
],
"display_pattern_list": [
{
"display_pattern_name": "0",
"display_code_list": [
"1",
"2"
]
}
]
},
{
"code_type": "RECEIVING_LIST1",
"code_list": [
{
"code": "1",
"code_name": "NAME"
}
],
"display_pattern_list": [
{
"display_pattern_name": "0",
"display_code_list": [
"1"
]
}
]
}
]
}
I need to convert this to Map with key-value pairs. How could I achieve this?
Using Jackson, you can do the following:
ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapper.writeValueAsString(commonCodeDetailList);
Map<String, String> map = mapper.readValue(jsonStr, Map.class);
First you need to convert commonCodeDetailList into a json string. After that you can convert this json string to map.