Get latest jsons with respect to [version and name] key in subjson in java
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
0
down vote
favorite
This is the json
[
"SUBTASK":
"id": 10,
"name": "TestMap",
"description": "",
"version":"1.0"
,
"SUBTASK":
"id": 23,
"name": "TestMap",
"description": "",
"version":"2.0"
,
"SUBTASK":
"id": 12,
"name": "Tree",
"description": "",
"version":"13.0"
,
"SUBTASK":
"id": 32,
"name": "Tree",
"description": "",
"version":"10.0"
]
Need to get latest among the number of SUBTASKS ie. filter the latest versions of SUBTASK with respected to name.
So the final json will be like:
final:["SUBTASK":"id":12.0,"name":"Tree","description":"","version":"13.0","SUBTASK":"id":23.0,"name":"TestMap","description":"","version":"2.0"]
I achived using the below the java code :
Java Snippet
public void getLatest(String json) throws Exception
// converting json to java Object
List<Map<String, Object>> taskList = new Gson().fromJson(json, new TypeToken<List<Map<String, Object>>>()
.getType());
Map<String, Object> taskVersionedMap = new HashMap<String, Object>();
for (int i = 0; i < taskList.size(); i++)
Map<String, Object> processMap = taskList.get(i);
Map<String, Object> process = (Map<String, Object>) processMap.get("SUBTASK");
String process_name = process.get("name").toString() + "_" + process.get("version");
taskVersionedMap.put(process_name, processMap);
for (Map.Entry<String, Object> entry : taskVersionedMap.entrySet())
String split = entry.getKey().split("_");
double version = Double.parseDouble(split[1]);
String name = split[0];
for (Map.Entry<String, Object> entry2 : taskVersionedMap.entrySet())
String split_2 = entry2.getKey().split("_");
double version_2 = Double.parseDouble(split_2[1]);
String name_2 = split_2[0];
if (name.equals(name_2))
if (version < version_2)
String removedProcessName = name + "_" + version;
taskVersionedMap.put(removedProcessName, "ignored");
List<Map<String, Object>> filteredVersionList = new ArrayList<Map<String, Object>>();
for (Map.Entry<String, Object> mapValues : taskVersionedMap.entrySet())
if (!mapValues.getValue().toString().equals("ignored"))
try
filteredVersionList.add((Map<String, Object>) mapValues.getValue());
catch (Exception e)
e.printStackTrace();
System.out.println("final:"+new Gson().toJson(filteredVersionList));
The above code gives accurate result expected and is time consuming.
But is it possible to optimize the code since real data json at process will be verry big almost 500 more subtasks
java json gson
add a comment |Â
up vote
0
down vote
favorite
This is the json
[
"SUBTASK":
"id": 10,
"name": "TestMap",
"description": "",
"version":"1.0"
,
"SUBTASK":
"id": 23,
"name": "TestMap",
"description": "",
"version":"2.0"
,
"SUBTASK":
"id": 12,
"name": "Tree",
"description": "",
"version":"13.0"
,
"SUBTASK":
"id": 32,
"name": "Tree",
"description": "",
"version":"10.0"
]
Need to get latest among the number of SUBTASKS ie. filter the latest versions of SUBTASK with respected to name.
So the final json will be like:
final:["SUBTASK":"id":12.0,"name":"Tree","description":"","version":"13.0","SUBTASK":"id":23.0,"name":"TestMap","description":"","version":"2.0"]
I achived using the below the java code :
Java Snippet
public void getLatest(String json) throws Exception
// converting json to java Object
List<Map<String, Object>> taskList = new Gson().fromJson(json, new TypeToken<List<Map<String, Object>>>()
.getType());
Map<String, Object> taskVersionedMap = new HashMap<String, Object>();
for (int i = 0; i < taskList.size(); i++)
Map<String, Object> processMap = taskList.get(i);
Map<String, Object> process = (Map<String, Object>) processMap.get("SUBTASK");
String process_name = process.get("name").toString() + "_" + process.get("version");
taskVersionedMap.put(process_name, processMap);
for (Map.Entry<String, Object> entry : taskVersionedMap.entrySet())
String split = entry.getKey().split("_");
double version = Double.parseDouble(split[1]);
String name = split[0];
for (Map.Entry<String, Object> entry2 : taskVersionedMap.entrySet())
String split_2 = entry2.getKey().split("_");
double version_2 = Double.parseDouble(split_2[1]);
String name_2 = split_2[0];
if (name.equals(name_2))
if (version < version_2)
String removedProcessName = name + "_" + version;
taskVersionedMap.put(removedProcessName, "ignored");
List<Map<String, Object>> filteredVersionList = new ArrayList<Map<String, Object>>();
for (Map.Entry<String, Object> mapValues : taskVersionedMap.entrySet())
if (!mapValues.getValue().toString().equals("ignored"))
try
filteredVersionList.add((Map<String, Object>) mapValues.getValue());
catch (Exception e)
e.printStackTrace();
System.out.println("final:"+new Gson().toJson(filteredVersionList));
The above code gives accurate result expected and is time consuming.
But is it possible to optimize the code since real data json at process will be verry big almost 500 more subtasks
java json gson
add a comment |Â
up vote
0
down vote
favorite
up vote
0
down vote
favorite
This is the json
[
"SUBTASK":
"id": 10,
"name": "TestMap",
"description": "",
"version":"1.0"
,
"SUBTASK":
"id": 23,
"name": "TestMap",
"description": "",
"version":"2.0"
,
"SUBTASK":
"id": 12,
"name": "Tree",
"description": "",
"version":"13.0"
,
"SUBTASK":
"id": 32,
"name": "Tree",
"description": "",
"version":"10.0"
]
Need to get latest among the number of SUBTASKS ie. filter the latest versions of SUBTASK with respected to name.
So the final json will be like:
final:["SUBTASK":"id":12.0,"name":"Tree","description":"","version":"13.0","SUBTASK":"id":23.0,"name":"TestMap","description":"","version":"2.0"]
I achived using the below the java code :
Java Snippet
public void getLatest(String json) throws Exception
// converting json to java Object
List<Map<String, Object>> taskList = new Gson().fromJson(json, new TypeToken<List<Map<String, Object>>>()
.getType());
Map<String, Object> taskVersionedMap = new HashMap<String, Object>();
for (int i = 0; i < taskList.size(); i++)
Map<String, Object> processMap = taskList.get(i);
Map<String, Object> process = (Map<String, Object>) processMap.get("SUBTASK");
String process_name = process.get("name").toString() + "_" + process.get("version");
taskVersionedMap.put(process_name, processMap);
for (Map.Entry<String, Object> entry : taskVersionedMap.entrySet())
String split = entry.getKey().split("_");
double version = Double.parseDouble(split[1]);
String name = split[0];
for (Map.Entry<String, Object> entry2 : taskVersionedMap.entrySet())
String split_2 = entry2.getKey().split("_");
double version_2 = Double.parseDouble(split_2[1]);
String name_2 = split_2[0];
if (name.equals(name_2))
if (version < version_2)
String removedProcessName = name + "_" + version;
taskVersionedMap.put(removedProcessName, "ignored");
List<Map<String, Object>> filteredVersionList = new ArrayList<Map<String, Object>>();
for (Map.Entry<String, Object> mapValues : taskVersionedMap.entrySet())
if (!mapValues.getValue().toString().equals("ignored"))
try
filteredVersionList.add((Map<String, Object>) mapValues.getValue());
catch (Exception e)
e.printStackTrace();
System.out.println("final:"+new Gson().toJson(filteredVersionList));
The above code gives accurate result expected and is time consuming.
But is it possible to optimize the code since real data json at process will be verry big almost 500 more subtasks
java json gson
This is the json
[
"SUBTASK":
"id": 10,
"name": "TestMap",
"description": "",
"version":"1.0"
,
"SUBTASK":
"id": 23,
"name": "TestMap",
"description": "",
"version":"2.0"
,
"SUBTASK":
"id": 12,
"name": "Tree",
"description": "",
"version":"13.0"
,
"SUBTASK":
"id": 32,
"name": "Tree",
"description": "",
"version":"10.0"
]
Need to get latest among the number of SUBTASKS ie. filter the latest versions of SUBTASK with respected to name.
So the final json will be like:
final:["SUBTASK":"id":12.0,"name":"Tree","description":"","version":"13.0","SUBTASK":"id":23.0,"name":"TestMap","description":"","version":"2.0"]
I achived using the below the java code :
Java Snippet
public void getLatest(String json) throws Exception
// converting json to java Object
List<Map<String, Object>> taskList = new Gson().fromJson(json, new TypeToken<List<Map<String, Object>>>()
.getType());
Map<String, Object> taskVersionedMap = new HashMap<String, Object>();
for (int i = 0; i < taskList.size(); i++)
Map<String, Object> processMap = taskList.get(i);
Map<String, Object> process = (Map<String, Object>) processMap.get("SUBTASK");
String process_name = process.get("name").toString() + "_" + process.get("version");
taskVersionedMap.put(process_name, processMap);
for (Map.Entry<String, Object> entry : taskVersionedMap.entrySet())
String split = entry.getKey().split("_");
double version = Double.parseDouble(split[1]);
String name = split[0];
for (Map.Entry<String, Object> entry2 : taskVersionedMap.entrySet())
String split_2 = entry2.getKey().split("_");
double version_2 = Double.parseDouble(split_2[1]);
String name_2 = split_2[0];
if (name.equals(name_2))
if (version < version_2)
String removedProcessName = name + "_" + version;
taskVersionedMap.put(removedProcessName, "ignored");
List<Map<String, Object>> filteredVersionList = new ArrayList<Map<String, Object>>();
for (Map.Entry<String, Object> mapValues : taskVersionedMap.entrySet())
if (!mapValues.getValue().toString().equals("ignored"))
try
filteredVersionList.add((Map<String, Object>) mapValues.getValue());
catch (Exception e)
e.printStackTrace();
System.out.println("final:"+new Gson().toJson(filteredVersionList));
The above code gives accurate result expected and is time consuming.
But is it possible to optimize the code since real data json at process will be verry big almost 500 more subtasks
java json gson
asked Jun 5 at 10:13
Kishan C S
1032
1032
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
First of all, you have a grouping operation by process name, then you have the task of finding the maximum by version number per group.
Thus, instead of using nested loops and somehow mashing it all together, simply perform those operations.
As standard operations like grouping and finding a maximum are alreay presenet in the java stream api, all we need is a few helpers to extract the name and the version:
Function<Map<String, Object>, String> extractName = m -> (String) ((Map<String, Object>) m.get("SUBTASK")).get("name");
ToDoubleFunction<Map<String, Object>> extractVersion = m -> Double.parseDouble((String) ((Map<String, Object>) m.get("SUBTASK")).get("version"));
Then, first group by name:
Map<String, List<Map<String, Object>>> byName = taskList.stream()
.collect(Collectors.groupingBy(extractName));
... which gives you a list of each task type in the value lists.
Now, we can disregard the grouping keys and extract the maximum per list:
List<Map<String, Object>> result = byName.values().stream()
.map(l -> l.stream().max(Comparator.comparingDouble(extractVersion)))
.map(Optional::get)
.collect(Collectors.toList());
Note: the stream.max returns an optional, which would be unset for an empty list. As we cannot generate empty lists here, it is save to simply map via Optional::get
to retrieve the value.
All is left is to encode the result list back to json, e.g.
String jsonResult = new GsonBuilder().setPrettyPrinting().create().toJson(result);
Note however, that you should better use a method which operates directly on the data structures, i.e. input and output are List<Map<String, Object>>
and another outer wrapper method to do the decoding and encoding. Do one thing in a method.
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
First of all, you have a grouping operation by process name, then you have the task of finding the maximum by version number per group.
Thus, instead of using nested loops and somehow mashing it all together, simply perform those operations.
As standard operations like grouping and finding a maximum are alreay presenet in the java stream api, all we need is a few helpers to extract the name and the version:
Function<Map<String, Object>, String> extractName = m -> (String) ((Map<String, Object>) m.get("SUBTASK")).get("name");
ToDoubleFunction<Map<String, Object>> extractVersion = m -> Double.parseDouble((String) ((Map<String, Object>) m.get("SUBTASK")).get("version"));
Then, first group by name:
Map<String, List<Map<String, Object>>> byName = taskList.stream()
.collect(Collectors.groupingBy(extractName));
... which gives you a list of each task type in the value lists.
Now, we can disregard the grouping keys and extract the maximum per list:
List<Map<String, Object>> result = byName.values().stream()
.map(l -> l.stream().max(Comparator.comparingDouble(extractVersion)))
.map(Optional::get)
.collect(Collectors.toList());
Note: the stream.max returns an optional, which would be unset for an empty list. As we cannot generate empty lists here, it is save to simply map via Optional::get
to retrieve the value.
All is left is to encode the result list back to json, e.g.
String jsonResult = new GsonBuilder().setPrettyPrinting().create().toJson(result);
Note however, that you should better use a method which operates directly on the data structures, i.e. input and output are List<Map<String, Object>>
and another outer wrapper method to do the decoding and encoding. Do one thing in a method.
add a comment |Â
up vote
2
down vote
accepted
First of all, you have a grouping operation by process name, then you have the task of finding the maximum by version number per group.
Thus, instead of using nested loops and somehow mashing it all together, simply perform those operations.
As standard operations like grouping and finding a maximum are alreay presenet in the java stream api, all we need is a few helpers to extract the name and the version:
Function<Map<String, Object>, String> extractName = m -> (String) ((Map<String, Object>) m.get("SUBTASK")).get("name");
ToDoubleFunction<Map<String, Object>> extractVersion = m -> Double.parseDouble((String) ((Map<String, Object>) m.get("SUBTASK")).get("version"));
Then, first group by name:
Map<String, List<Map<String, Object>>> byName = taskList.stream()
.collect(Collectors.groupingBy(extractName));
... which gives you a list of each task type in the value lists.
Now, we can disregard the grouping keys and extract the maximum per list:
List<Map<String, Object>> result = byName.values().stream()
.map(l -> l.stream().max(Comparator.comparingDouble(extractVersion)))
.map(Optional::get)
.collect(Collectors.toList());
Note: the stream.max returns an optional, which would be unset for an empty list. As we cannot generate empty lists here, it is save to simply map via Optional::get
to retrieve the value.
All is left is to encode the result list back to json, e.g.
String jsonResult = new GsonBuilder().setPrettyPrinting().create().toJson(result);
Note however, that you should better use a method which operates directly on the data structures, i.e. input and output are List<Map<String, Object>>
and another outer wrapper method to do the decoding and encoding. Do one thing in a method.
add a comment |Â
up vote
2
down vote
accepted
up vote
2
down vote
accepted
First of all, you have a grouping operation by process name, then you have the task of finding the maximum by version number per group.
Thus, instead of using nested loops and somehow mashing it all together, simply perform those operations.
As standard operations like grouping and finding a maximum are alreay presenet in the java stream api, all we need is a few helpers to extract the name and the version:
Function<Map<String, Object>, String> extractName = m -> (String) ((Map<String, Object>) m.get("SUBTASK")).get("name");
ToDoubleFunction<Map<String, Object>> extractVersion = m -> Double.parseDouble((String) ((Map<String, Object>) m.get("SUBTASK")).get("version"));
Then, first group by name:
Map<String, List<Map<String, Object>>> byName = taskList.stream()
.collect(Collectors.groupingBy(extractName));
... which gives you a list of each task type in the value lists.
Now, we can disregard the grouping keys and extract the maximum per list:
List<Map<String, Object>> result = byName.values().stream()
.map(l -> l.stream().max(Comparator.comparingDouble(extractVersion)))
.map(Optional::get)
.collect(Collectors.toList());
Note: the stream.max returns an optional, which would be unset for an empty list. As we cannot generate empty lists here, it is save to simply map via Optional::get
to retrieve the value.
All is left is to encode the result list back to json, e.g.
String jsonResult = new GsonBuilder().setPrettyPrinting().create().toJson(result);
Note however, that you should better use a method which operates directly on the data structures, i.e. input and output are List<Map<String, Object>>
and another outer wrapper method to do the decoding and encoding. Do one thing in a method.
First of all, you have a grouping operation by process name, then you have the task of finding the maximum by version number per group.
Thus, instead of using nested loops and somehow mashing it all together, simply perform those operations.
As standard operations like grouping and finding a maximum are alreay presenet in the java stream api, all we need is a few helpers to extract the name and the version:
Function<Map<String, Object>, String> extractName = m -> (String) ((Map<String, Object>) m.get("SUBTASK")).get("name");
ToDoubleFunction<Map<String, Object>> extractVersion = m -> Double.parseDouble((String) ((Map<String, Object>) m.get("SUBTASK")).get("version"));
Then, first group by name:
Map<String, List<Map<String, Object>>> byName = taskList.stream()
.collect(Collectors.groupingBy(extractName));
... which gives you a list of each task type in the value lists.
Now, we can disregard the grouping keys and extract the maximum per list:
List<Map<String, Object>> result = byName.values().stream()
.map(l -> l.stream().max(Comparator.comparingDouble(extractVersion)))
.map(Optional::get)
.collect(Collectors.toList());
Note: the stream.max returns an optional, which would be unset for an empty list. As we cannot generate empty lists here, it is save to simply map via Optional::get
to retrieve the value.
All is left is to encode the result list back to json, e.g.
String jsonResult = new GsonBuilder().setPrettyPrinting().create().toJson(result);
Note however, that you should better use a method which operates directly on the data structures, i.e. input and output are List<Map<String, Object>>
and another outer wrapper method to do the decoding and encoding. Do one thing in a method.
answered Jun 5 at 10:41
mtj
2,675212
2,675212
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195875%2fget-latest-jsons-with-respect-to-version-and-name-key-in-subjson-in-java%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password